zeitlich 0.2.50 → 0.2.51
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/adapters/thread/anthropic/index.cjs +15 -13
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +15 -10
- package/dist/adapters/thread/anthropic/index.d.ts +15 -10
- package/dist/adapters/thread/anthropic/index.js +15 -13
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
- package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
- package/dist/adapters/thread/google-genai/index.cjs +18 -12
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +181 -11
- package/dist/adapters/thread/google-genai/index.d.ts +181 -11
- package/dist/adapters/thread/google-genai/index.js +18 -12
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +6 -6
- package/dist/adapters/thread/google-genai/workflow.d.ts +6 -6
- package/dist/adapters/thread/langchain/index.cjs +22 -13
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +15 -10
- package/dist/adapters/thread/langchain/index.d.ts +15 -10
- package/dist/adapters/thread/langchain/index.js +22 -13
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
- package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
- package/dist/{cold-store-CCnZYWjx.d.ts → cold-store-DyHodfAB.d.ts} +1 -1
- package/dist/{cold-store-C0uvYTSi.d.cts → cold-store-YOx9nmgR.d.cts} +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/{proxy-BVznA2_p.d.cts → proxy-2htgGQrc.d.cts} +1 -1
- package/dist/{proxy-C4J1pNUk.d.ts → proxy-CmiTP4pp.d.ts} +1 -1
- package/dist/{thread-manager-BqjzWsP7.d.ts → thread-manager-BJ5pz5Cx.d.cts} +4 -5
- package/dist/{thread-manager-SkSWRPRc.d.ts → thread-manager-BQAbrYXH.d.cts} +4 -5
- package/dist/{thread-manager-Dzl1fHhV.d.cts → thread-manager-CcvltOuq.d.ts} +4 -5
- package/dist/{thread-manager-CzIs47uG.d.cts → thread-manager-DHAbncHX.d.ts} +4 -5
- package/dist/{types-DZnUqCAP.d.cts → types-BjdqxKYp.d.cts} +1 -1
- package/dist/{types-CbPnU4RM.d.ts → types-DEbkLA06.d.ts} +1 -1
- package/dist/{types-YNesmGKV.d.ts → types-DiI7mZhI.d.ts} +1 -1
- package/dist/{types-d2RvEP6v.d.cts → types-N_LTWe4b.d.cts} +1 -1
- package/dist/{workflow-B3oTe2_D.d.cts → workflow-CcgD6EUB.d.cts} +1 -1
- package/dist/{workflow-Bkzg0cjB.d.ts → workflow-DBjPOKBr.d.ts} +1 -1
- package/dist/workflow.d.cts +2 -2
- package/dist/workflow.d.ts +2 -2
- package/package.json +1 -1
- package/src/adapters/thread/anthropic/activities.test.ts +115 -0
- package/src/adapters/thread/anthropic/activities.ts +10 -18
- package/src/adapters/thread/anthropic/model-invoker.test.ts +50 -0
- package/src/adapters/thread/anthropic/model-invoker.ts +10 -0
- package/src/adapters/thread/anthropic/thread-manager.ts +2 -3
- package/src/adapters/thread/google-genai/activities.test.ts +162 -0
- package/src/adapters/thread/google-genai/activities.ts +37 -14
- package/src/adapters/thread/google-genai/model-invoker.test.ts +53 -4
- package/src/adapters/thread/google-genai/model-invoker.ts +11 -0
- package/src/adapters/thread/google-genai/thread-manager.ts +2 -3
- package/src/adapters/thread/langchain/activities.test.ts +88 -0
- package/src/adapters/thread/langchain/activities.ts +14 -11
- package/src/adapters/thread/langchain/model-invoker.test.ts +74 -0
- package/src/adapters/thread/langchain/model-invoker.ts +15 -2
- package/src/adapters/thread/langchain/thread-manager.ts +2 -3
- package/dist/activities-IuOIvPHO.d.ts +0 -162
- package/dist/activities-cIlq1y1y.d.cts +0 -162
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RedisClientType } from 'redis';
|
|
2
2
|
import Anthropic from '@anthropic-ai/sdk';
|
|
3
|
-
import { J as JsonValue } from './types-
|
|
4
|
-
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-
|
|
3
|
+
import { J as JsonValue } from './types-DiI7mZhI.js';
|
|
4
|
+
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-DEbkLA06.js';
|
|
5
5
|
|
|
6
6
|
/** SDK-native content type for Anthropic human messages */
|
|
7
7
|
type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
|
|
@@ -22,9 +22,8 @@ interface AnthropicThreadManagerConfig {
|
|
|
22
22
|
key?: string;
|
|
23
23
|
hooks?: AnthropicThreadManagerHooks;
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* typically more appropriate.
|
|
25
|
+
* Redis TTL for the thread's keys; defaults to 90 days. Use a shorter
|
|
26
|
+
* value (hours) with a cold tier.
|
|
28
27
|
*/
|
|
29
28
|
ttlSeconds?: number;
|
|
30
29
|
}
|
|
@@ -1866,4 +1866,4 @@ interface ZeitlichSession<M = unknown, HasSandbox extends boolean = boolean> {
|
|
|
1866
1866
|
}): Promise<SessionResult<M, T, HasSandbox>>;
|
|
1867
1867
|
}
|
|
1868
1868
|
|
|
1869
|
-
export { type SandboxShutdown as $, type
|
|
1869
|
+
export { type SandboxShutdown as $, type ActivityToolHandler as A, type BaseAgentState as B, type PostToolUseFailureHookContext as C, type PostToolUseFailureHookResult as D, type PostToolUseHook as E, type FileEntryMetadata as F, type PostToolUseHookContext as G, type Hooks as H, type InferToolResults as I, type JsonValue as J, type PreHumanMessageAppendHook as K, type PreHumanMessageAppendHookContext as L, type ModelInvoker as M, type PreToolUseHook as N, type PreToolUseHookContext as O, type PersistedThreadState as P, type PreToolUseHookResult as Q, type RouterContext as R, type ScopedPrefix as S, type ThreadOps as T, type ProcessToolCallsContext as U, type VirtualFsContext as V, type ProcessToolCallsResult as W, type RawToolCall as X, type RewindSignal as Y, type RunAgentActivity as Z, type SandboxInit as _, type PrefixedThreadOps as a, type SerializableToolDefinition as a0, type SessionConfig as a1, type SessionEndHook as a2, type SessionEndHookContext as a3, type SessionExitReason as a4, type SessionRequiredCaps as a5, type SessionResult as a6, type SessionStartHook as a7, type SessionStartHookContext as a8, type SubagentChildWorkflowOptions as a9, VirtualFileSystem as aA, type VirtualFileTree as aB, type VirtualFsOps as aC, type VirtualFsState as aD, type WorkflowTask as aE, type ZeitlichSession as aF, isTerminalStatus as aG, type ToolRouterOptions as aH, type SubagentConfig as aa, type SubagentContinuationCaps as ab, type SubagentDefinition as ac, type SubagentFnResult as ad, type SubagentHandlerResponse as ae, type SubagentHooks as af, type SubagentSandboxConfig as ag, type SubagentSandboxShutdown as ah, type SubagentSessionInput as ai, type SubagentWorkflow as aj, type SubagentWorkflowInput as ak, type TaskStatus as al, type ThreadInit as am, type TokenUsage as an, type ToolArgs as ao, type ToolCallResult as ap, type ToolCallResultUnion as aq, type ToolDefinition as ar, type ToolHandler as as, type ToolHooks as at, type ToolMap as au, type ToolNames as av, type ToolResult as aw, type ToolRouter as ax, type ToolRouterHooks as ay, type ToolWithHandler as az, type ToolHandlerResponse as b, type ModelInvokerConfig as c, type AgentResponse as d, type RunAgentConfig as e, type ToolResultConfig as f, type SkillProvider as g, type SkillMetadata as h, type Skill as i, type FileResolver as j, type TreeMutation as k, type PrefixedVirtualFsOps as l, type AgentConfig as m, type AgentFile as n, type AgentState as o, type AgentStateManager as p, type AgentStatus as q, type AppendToolResultFn as r, type FileEntry as s, type JsonPrimitive as t, type JsonSerializable as u, type ParsedToolCall as v, type ParsedToolCallUnion as w, type PostHumanMessageAppendHook as x, type PostHumanMessageAppendHookContext as y, type PostToolUseFailureHook as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RedisClientType } from 'redis';
|
|
2
|
-
import { J as JsonValue, P as PersistedThreadState } from './types-
|
|
2
|
+
import { J as JsonValue, P as PersistedThreadState } from './types-DiI7mZhI.js';
|
|
3
3
|
|
|
4
4
|
interface ThreadManagerConfig<T> {
|
|
5
5
|
redis: RedisClientType;
|
|
@@ -1866,4 +1866,4 @@ interface ZeitlichSession<M = unknown, HasSandbox extends boolean = boolean> {
|
|
|
1866
1866
|
}): Promise<SessionResult<M, T, HasSandbox>>;
|
|
1867
1867
|
}
|
|
1868
1868
|
|
|
1869
|
-
export { type SandboxShutdown as $, type
|
|
1869
|
+
export { type SandboxShutdown as $, type ActivityToolHandler as A, type BaseAgentState as B, type PostToolUseFailureHookContext as C, type PostToolUseFailureHookResult as D, type PostToolUseHook as E, type FileEntryMetadata as F, type PostToolUseHookContext as G, type Hooks as H, type InferToolResults as I, type JsonValue as J, type PreHumanMessageAppendHook as K, type PreHumanMessageAppendHookContext as L, type ModelInvoker as M, type PreToolUseHook as N, type PreToolUseHookContext as O, type PersistedThreadState as P, type PreToolUseHookResult as Q, type RouterContext as R, type ScopedPrefix as S, type ThreadOps as T, type ProcessToolCallsContext as U, type VirtualFsContext as V, type ProcessToolCallsResult as W, type RawToolCall as X, type RewindSignal as Y, type RunAgentActivity as Z, type SandboxInit as _, type PrefixedThreadOps as a, type SerializableToolDefinition as a0, type SessionConfig as a1, type SessionEndHook as a2, type SessionEndHookContext as a3, type SessionExitReason as a4, type SessionRequiredCaps as a5, type SessionResult as a6, type SessionStartHook as a7, type SessionStartHookContext as a8, type SubagentChildWorkflowOptions as a9, VirtualFileSystem as aA, type VirtualFileTree as aB, type VirtualFsOps as aC, type VirtualFsState as aD, type WorkflowTask as aE, type ZeitlichSession as aF, isTerminalStatus as aG, type ToolRouterOptions as aH, type SubagentConfig as aa, type SubagentContinuationCaps as ab, type SubagentDefinition as ac, type SubagentFnResult as ad, type SubagentHandlerResponse as ae, type SubagentHooks as af, type SubagentSandboxConfig as ag, type SubagentSandboxShutdown as ah, type SubagentSessionInput as ai, type SubagentWorkflow as aj, type SubagentWorkflowInput as ak, type TaskStatus as al, type ThreadInit as am, type TokenUsage as an, type ToolArgs as ao, type ToolCallResult as ap, type ToolCallResultUnion as aq, type ToolDefinition as ar, type ToolHandler as as, type ToolHooks as at, type ToolMap as au, type ToolNames as av, type ToolResult as aw, type ToolRouter as ax, type ToolRouterHooks as ay, type ToolWithHandler as az, type ToolHandlerResponse as b, type ModelInvokerConfig as c, type AgentResponse as d, type RunAgentConfig as e, type ToolResultConfig as f, type SkillProvider as g, type SkillMetadata as h, type Skill as i, type FileResolver as j, type TreeMutation as k, type PrefixedVirtualFsOps as l, type AgentConfig as m, type AgentFile as n, type AgentState as o, type AgentStateManager as p, type AgentStatus as q, type AppendToolResultFn as r, type FileEntry as s, type JsonPrimitive as t, type JsonSerializable as u, type ParsedToolCall as v, type ParsedToolCallUnion as w, type PostHumanMessageAppendHook as x, type PostHumanMessageAppendHookContext as y, type PostToolUseFailureHook as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RedisClientType } from 'redis';
|
|
2
|
-
import { J as JsonValue, P as PersistedThreadState } from './types-
|
|
2
|
+
import { J as JsonValue, P as PersistedThreadState } from './types-BjdqxKYp.cjs';
|
|
3
3
|
|
|
4
4
|
interface ThreadManagerConfig<T> {
|
|
5
5
|
redis: RedisClientType;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, an as TokenUsage, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, e as RunAgentConfig,
|
|
1
|
+
import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, an as TokenUsage, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, e as RunAgentConfig, d as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, b as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, A as ActivityToolHandler } from './types-BjdqxKYp.cjs';
|
|
2
2
|
import { g as SandboxSnapshot } from './types-D8W5TnSa.cjs';
|
|
3
3
|
import z$1, { z } from 'zod';
|
|
4
4
|
import { Duration } from '@temporalio/common';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, an as TokenUsage, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, e as RunAgentConfig,
|
|
1
|
+
import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, an as TokenUsage, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, e as RunAgentConfig, d as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, b as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, A as ActivityToolHandler } from './types-DiI7mZhI.js';
|
|
2
2
|
import { g as SandboxSnapshot } from './types-D8W5TnSa.js';
|
|
3
3
|
import z$1, { z } from 'zod';
|
|
4
4
|
import { Duration } from '@temporalio/common';
|
package/dist/workflow.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as AskUserQuestionArgs, B as BashArgs, D as DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, F as FileEditArgs, a as FileMultiEditArgs, b as FileReadArgs, c as FileWriteArgs, G as GlobArgs, e as GrepArgs, O as ObservabilityHooks, R as ReadSkillArgs, S as SessionEndedEvent, f as SessionStartedEvent, g as SubagentArgs, T as THREAD_TTL_SECONDS, h as TaskCreateArgs, i as TaskGetArgs, j as TaskListArgs, k as TaskUpdateArgs, l as ToolExecutedEvent, m as TurnCompletedEvent, W as WorkflowConfig, n as WorkflowInput, o as WorkflowSessionInput, Z as ZeitlichObservabilitySinks, p as applyVirtualTreeMutations, q as askUserQuestionTool, r as bashTool, s as composeHooks, t as createAgentStateManager, u as createAskUserQuestionHandler, v as createBashToolDescription, w as createObservabilityHooks, x as createReadSkillHandler, y as createReadSkillTool, z as createSession, C as createTaskCreateHandler, E as createTaskGetHandler, H as createTaskListHandler, I as createTaskUpdateHandler, J as createToolRouter, K as defineSubagent, L as defineSubagentWorkflow, M as defineTool, N as defineWorkflow, P as editTool, Q as filesWithMimeType, U as formatVirtualFileTree, V as getShortId, Y as getThreadListKey, _ as getThreadMetaKey, a0 as globTool, a1 as grepTool, a2 as hasDirectory, a3 as hasFileWithMimeType, a4 as hasNoOtherToolCalls, a5 as multiEditTool, a6 as parseSkillFile, a7 as proxyRunAgent, a8 as proxyVirtualFsOps, a9 as readFileTool, aa as taskCreateTool, ab as taskGetTool, ac as taskListTool, ad as taskUpdateTool, ae as writeFileTool } from './workflow-
|
|
2
|
-
export {
|
|
1
|
+
export { A as AskUserQuestionArgs, B as BashArgs, D as DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, F as FileEditArgs, a as FileMultiEditArgs, b as FileReadArgs, c as FileWriteArgs, G as GlobArgs, e as GrepArgs, O as ObservabilityHooks, R as ReadSkillArgs, S as SessionEndedEvent, f as SessionStartedEvent, g as SubagentArgs, T as THREAD_TTL_SECONDS, h as TaskCreateArgs, i as TaskGetArgs, j as TaskListArgs, k as TaskUpdateArgs, l as ToolExecutedEvent, m as TurnCompletedEvent, W as WorkflowConfig, n as WorkflowInput, o as WorkflowSessionInput, Z as ZeitlichObservabilitySinks, p as applyVirtualTreeMutations, q as askUserQuestionTool, r as bashTool, s as composeHooks, t as createAgentStateManager, u as createAskUserQuestionHandler, v as createBashToolDescription, w as createObservabilityHooks, x as createReadSkillHandler, y as createReadSkillTool, z as createSession, C as createTaskCreateHandler, E as createTaskGetHandler, H as createTaskListHandler, I as createTaskUpdateHandler, J as createToolRouter, K as defineSubagent, L as defineSubagentWorkflow, M as defineTool, N as defineWorkflow, P as editTool, Q as filesWithMimeType, U as formatVirtualFileTree, V as getShortId, Y as getThreadListKey, _ as getThreadMetaKey, a0 as globTool, a1 as grepTool, a2 as hasDirectory, a3 as hasFileWithMimeType, a4 as hasNoOtherToolCalls, a5 as multiEditTool, a6 as parseSkillFile, a7 as proxyRunAgent, a8 as proxyVirtualFsOps, a9 as readFileTool, aa as taskCreateTool, ab as taskGetTool, ac as taskListTool, ad as taskUpdateTool, ae as writeFileTool } from './workflow-CcgD6EUB.cjs';
|
|
2
|
+
export { A as ActivityToolHandler, m as AgentConfig, n as AgentFile, d as AgentResponse, o as AgentState, p as AgentStateManager, q as AgentStatus, r as AppendToolResultFn, B as BaseAgentState, s as FileEntry, F as FileEntryMetadata, j as FileResolver, H as Hooks, I as InferToolResults, t as JsonPrimitive, u as JsonSerializable, J as JsonValue, M as ModelInvoker, c as ModelInvokerConfig, v as ParsedToolCall, w as ParsedToolCallUnion, P as PersistedThreadState, x as PostHumanMessageAppendHook, y as PostHumanMessageAppendHookContext, z as PostToolUseFailureHook, C as PostToolUseFailureHookContext, D as PostToolUseFailureHookResult, E as PostToolUseHook, G as PostToolUseHookContext, K as PreHumanMessageAppendHook, L as PreHumanMessageAppendHookContext, N as PreToolUseHook, O as PreToolUseHookContext, Q as PreToolUseHookResult, a as PrefixedThreadOps, l as PrefixedVirtualFsOps, U as ProcessToolCallsContext, W as ProcessToolCallsResult, X as RawToolCall, Y as RewindSignal, R as RouterContext, Z as RunAgentActivity, e as RunAgentConfig, _ as SandboxInit, $ as SandboxShutdown, S as ScopedPrefix, a0 as SerializableToolDefinition, a1 as SessionConfig, a2 as SessionEndHook, a3 as SessionEndHookContext, a4 as SessionExitReason, a5 as SessionRequiredCaps, a6 as SessionResult, a7 as SessionStartHook, a8 as SessionStartHookContext, i as Skill, h as SkillMetadata, g as SkillProvider, a9 as SubagentChildWorkflowOptions, aa as SubagentConfig, ab as SubagentContinuationCaps, ac as SubagentDefinition, ad as SubagentFnResult, ae as SubagentHandlerResponse, af as SubagentHooks, ag as SubagentSandboxConfig, ah as SubagentSandboxShutdown, ai as SubagentSessionInput, aj as SubagentWorkflow, ak as SubagentWorkflowInput, al as TaskStatus, am as ThreadInit, T as ThreadOps, an as TokenUsage, ao as ToolArgs, ap as ToolCallResult, aq as ToolCallResultUnion, ar as ToolDefinition, as as ToolHandler, b as ToolHandlerResponse, at as ToolHooks, au as ToolMap, av as ToolNames, aw as ToolResult, f as ToolResultConfig, ax as ToolRouter, ay as ToolRouterHooks, az as ToolWithHandler, k as TreeMutation, aB as VirtualFileTree, aC as VirtualFsOps, aD as VirtualFsState, aE as WorkflowTask, aF as ZeitlichSession, aG as isTerminalStatus } from './types-BjdqxKYp.cjs';
|
|
3
3
|
export { i as ExecOptions, E as ExecResult, P as PrefixedSandboxOps, e as Sandbox, a as SandboxCapabilities, h as SandboxCapability, f as SandboxCreateOptions, b as SandboxCreateResult, D as SandboxDirentEntry, F as SandboxFileStat, d as SandboxFileSystem, j as SandboxNotFoundError, k as SandboxNotSupportedError, c as SandboxOps, S as SandboxProvider, g as SandboxSnapshot } from './types-D8W5TnSa.cjs';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import '@temporalio/common';
|
package/dist/workflow.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as AskUserQuestionArgs, B as BashArgs, D as DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, F as FileEditArgs, a as FileMultiEditArgs, b as FileReadArgs, c as FileWriteArgs, G as GlobArgs, e as GrepArgs, O as ObservabilityHooks, R as ReadSkillArgs, S as SessionEndedEvent, f as SessionStartedEvent, g as SubagentArgs, T as THREAD_TTL_SECONDS, h as TaskCreateArgs, i as TaskGetArgs, j as TaskListArgs, k as TaskUpdateArgs, l as ToolExecutedEvent, m as TurnCompletedEvent, W as WorkflowConfig, n as WorkflowInput, o as WorkflowSessionInput, Z as ZeitlichObservabilitySinks, p as applyVirtualTreeMutations, q as askUserQuestionTool, r as bashTool, s as composeHooks, t as createAgentStateManager, u as createAskUserQuestionHandler, v as createBashToolDescription, w as createObservabilityHooks, x as createReadSkillHandler, y as createReadSkillTool, z as createSession, C as createTaskCreateHandler, E as createTaskGetHandler, H as createTaskListHandler, I as createTaskUpdateHandler, J as createToolRouter, K as defineSubagent, L as defineSubagentWorkflow, M as defineTool, N as defineWorkflow, P as editTool, Q as filesWithMimeType, U as formatVirtualFileTree, V as getShortId, Y as getThreadListKey, _ as getThreadMetaKey, a0 as globTool, a1 as grepTool, a2 as hasDirectory, a3 as hasFileWithMimeType, a4 as hasNoOtherToolCalls, a5 as multiEditTool, a6 as parseSkillFile, a7 as proxyRunAgent, a8 as proxyVirtualFsOps, a9 as readFileTool, aa as taskCreateTool, ab as taskGetTool, ac as taskListTool, ad as taskUpdateTool, ae as writeFileTool } from './workflow-
|
|
2
|
-
export {
|
|
1
|
+
export { A as AskUserQuestionArgs, B as BashArgs, D as DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, F as FileEditArgs, a as FileMultiEditArgs, b as FileReadArgs, c as FileWriteArgs, G as GlobArgs, e as GrepArgs, O as ObservabilityHooks, R as ReadSkillArgs, S as SessionEndedEvent, f as SessionStartedEvent, g as SubagentArgs, T as THREAD_TTL_SECONDS, h as TaskCreateArgs, i as TaskGetArgs, j as TaskListArgs, k as TaskUpdateArgs, l as ToolExecutedEvent, m as TurnCompletedEvent, W as WorkflowConfig, n as WorkflowInput, o as WorkflowSessionInput, Z as ZeitlichObservabilitySinks, p as applyVirtualTreeMutations, q as askUserQuestionTool, r as bashTool, s as composeHooks, t as createAgentStateManager, u as createAskUserQuestionHandler, v as createBashToolDescription, w as createObservabilityHooks, x as createReadSkillHandler, y as createReadSkillTool, z as createSession, C as createTaskCreateHandler, E as createTaskGetHandler, H as createTaskListHandler, I as createTaskUpdateHandler, J as createToolRouter, K as defineSubagent, L as defineSubagentWorkflow, M as defineTool, N as defineWorkflow, P as editTool, Q as filesWithMimeType, U as formatVirtualFileTree, V as getShortId, Y as getThreadListKey, _ as getThreadMetaKey, a0 as globTool, a1 as grepTool, a2 as hasDirectory, a3 as hasFileWithMimeType, a4 as hasNoOtherToolCalls, a5 as multiEditTool, a6 as parseSkillFile, a7 as proxyRunAgent, a8 as proxyVirtualFsOps, a9 as readFileTool, aa as taskCreateTool, ab as taskGetTool, ac as taskListTool, ad as taskUpdateTool, ae as writeFileTool } from './workflow-DBjPOKBr.js';
|
|
2
|
+
export { A as ActivityToolHandler, m as AgentConfig, n as AgentFile, d as AgentResponse, o as AgentState, p as AgentStateManager, q as AgentStatus, r as AppendToolResultFn, B as BaseAgentState, s as FileEntry, F as FileEntryMetadata, j as FileResolver, H as Hooks, I as InferToolResults, t as JsonPrimitive, u as JsonSerializable, J as JsonValue, M as ModelInvoker, c as ModelInvokerConfig, v as ParsedToolCall, w as ParsedToolCallUnion, P as PersistedThreadState, x as PostHumanMessageAppendHook, y as PostHumanMessageAppendHookContext, z as PostToolUseFailureHook, C as PostToolUseFailureHookContext, D as PostToolUseFailureHookResult, E as PostToolUseHook, G as PostToolUseHookContext, K as PreHumanMessageAppendHook, L as PreHumanMessageAppendHookContext, N as PreToolUseHook, O as PreToolUseHookContext, Q as PreToolUseHookResult, a as PrefixedThreadOps, l as PrefixedVirtualFsOps, U as ProcessToolCallsContext, W as ProcessToolCallsResult, X as RawToolCall, Y as RewindSignal, R as RouterContext, Z as RunAgentActivity, e as RunAgentConfig, _ as SandboxInit, $ as SandboxShutdown, S as ScopedPrefix, a0 as SerializableToolDefinition, a1 as SessionConfig, a2 as SessionEndHook, a3 as SessionEndHookContext, a4 as SessionExitReason, a5 as SessionRequiredCaps, a6 as SessionResult, a7 as SessionStartHook, a8 as SessionStartHookContext, i as Skill, h as SkillMetadata, g as SkillProvider, a9 as SubagentChildWorkflowOptions, aa as SubagentConfig, ab as SubagentContinuationCaps, ac as SubagentDefinition, ad as SubagentFnResult, ae as SubagentHandlerResponse, af as SubagentHooks, ag as SubagentSandboxConfig, ah as SubagentSandboxShutdown, ai as SubagentSessionInput, aj as SubagentWorkflow, ak as SubagentWorkflowInput, al as TaskStatus, am as ThreadInit, T as ThreadOps, an as TokenUsage, ao as ToolArgs, ap as ToolCallResult, aq as ToolCallResultUnion, ar as ToolDefinition, as as ToolHandler, b as ToolHandlerResponse, at as ToolHooks, au as ToolMap, av as ToolNames, aw as ToolResult, f as ToolResultConfig, ax as ToolRouter, ay as ToolRouterHooks, az as ToolWithHandler, k as TreeMutation, aB as VirtualFileTree, aC as VirtualFsOps, aD as VirtualFsState, aE as WorkflowTask, aF as ZeitlichSession, aG as isTerminalStatus } from './types-DiI7mZhI.js';
|
|
3
3
|
export { i as ExecOptions, E as ExecResult, P as PrefixedSandboxOps, e as Sandbox, a as SandboxCapabilities, h as SandboxCapability, f as SandboxCreateOptions, b as SandboxCreateResult, D as SandboxDirentEntry, F as SandboxFileStat, d as SandboxFileSystem, j as SandboxNotFoundError, k as SandboxNotSupportedError, c as SandboxOps, S as SandboxProvider, g as SandboxSnapshot } from './types-D8W5TnSa.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import '@temporalio/common';
|
package/package.json
CHANGED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import type Anthropic from "@anthropic-ai/sdk";
|
|
3
|
+
import { createAnthropicAdapter } from "./activities";
|
|
4
|
+
import type { StoredMessage } from "./thread-manager";
|
|
5
|
+
import { THREAD_TTL_SECONDS } from "../../../lib/thread/keys";
|
|
6
|
+
|
|
7
|
+
function createMockRedis(stored: StoredMessage[]) {
|
|
8
|
+
return {
|
|
9
|
+
exists: vi.fn().mockResolvedValue(1),
|
|
10
|
+
lRange: vi.fn().mockResolvedValue(stored.map((m) => JSON.stringify(m))),
|
|
11
|
+
lTrim: vi.fn().mockResolvedValue("OK"),
|
|
12
|
+
del: vi.fn().mockResolvedValue(1),
|
|
13
|
+
set: vi.fn().mockResolvedValue("OK"),
|
|
14
|
+
rPush: vi.fn().mockResolvedValue(1),
|
|
15
|
+
expire: vi.fn().mockResolvedValue(1),
|
|
16
|
+
eval: vi.fn().mockResolvedValue(1),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function createMockClient() {
|
|
21
|
+
const finalMessage: Anthropic.Messages.Message = {
|
|
22
|
+
id: "msg-response",
|
|
23
|
+
type: "message",
|
|
24
|
+
role: "assistant",
|
|
25
|
+
container: null,
|
|
26
|
+
model: "claude-test",
|
|
27
|
+
content: [{ type: "text", text: "ok", citations: null }],
|
|
28
|
+
stop_details: null,
|
|
29
|
+
stop_reason: "end_turn",
|
|
30
|
+
stop_sequence: null,
|
|
31
|
+
usage: {
|
|
32
|
+
cache_creation: null,
|
|
33
|
+
cache_creation_input_tokens: null,
|
|
34
|
+
cache_read_input_tokens: null,
|
|
35
|
+
inference_geo: null,
|
|
36
|
+
input_tokens: 1,
|
|
37
|
+
output_tokens: 1,
|
|
38
|
+
server_tool_use: null,
|
|
39
|
+
service_tier: null,
|
|
40
|
+
output_tokens_details: null,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
const stream = {
|
|
44
|
+
async *[Symbol.asyncIterator]() {},
|
|
45
|
+
finalMessage: vi.fn().mockResolvedValue(finalMessage),
|
|
46
|
+
};
|
|
47
|
+
return { messages: { stream: vi.fn().mockReturnValue(stream) } };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Tail stored under the `assistantMessageId`, so the invoker's
|
|
51
|
+
// `truncateFromId` trims it and re-stamps the surviving list key's TTL.
|
|
52
|
+
const retriedThread: StoredMessage[] = [
|
|
53
|
+
{ id: "msg-1", message: { role: "user", content: "hi" } },
|
|
54
|
+
{ id: "assistant-1", message: { role: "assistant", content: "prior" } },
|
|
55
|
+
];
|
|
56
|
+
const listKey = "messages:thread:thread-1";
|
|
57
|
+
const metaKey = "messages:meta:thread:thread-1";
|
|
58
|
+
const invokerCall = {
|
|
59
|
+
threadId: "thread-1",
|
|
60
|
+
assistantMessageId: "assistant-1",
|
|
61
|
+
state: { tools: [] } as never,
|
|
62
|
+
agentName: "TestAgent",
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
describe("createAnthropicAdapter — TTL propagation", () => {
|
|
66
|
+
it("forwards adapter ttlSeconds to a created invoker's writes", async () => {
|
|
67
|
+
const redis = createMockRedis(retriedThread);
|
|
68
|
+
const client = createMockClient();
|
|
69
|
+
const adapter = createAnthropicAdapter({
|
|
70
|
+
redis: redis as never,
|
|
71
|
+
client: client as never,
|
|
72
|
+
ttlSeconds: 3600,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
await adapter.createModelInvoker("claude-test")(invokerCall);
|
|
76
|
+
|
|
77
|
+
expect(redis.expire).toHaveBeenCalledWith(listKey, 3600);
|
|
78
|
+
expect(redis.expire).not.toHaveBeenCalledWith(listKey, THREAD_TTL_SECONDS);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("forwards adapter ttlSeconds to thread-op writes", async () => {
|
|
82
|
+
const redis = createMockRedis([]);
|
|
83
|
+
const client = createMockClient();
|
|
84
|
+
const adapter = createAnthropicAdapter({
|
|
85
|
+
redis: redis as never,
|
|
86
|
+
client: client as never,
|
|
87
|
+
ttlSeconds: 3600,
|
|
88
|
+
});
|
|
89
|
+
const acts = adapter.createActivities() as unknown as Record<
|
|
90
|
+
string,
|
|
91
|
+
(threadId: string, threadKey?: string) => Promise<void>
|
|
92
|
+
>;
|
|
93
|
+
const initialize = Object.entries(acts).find(([k]) =>
|
|
94
|
+
k.endsWith("InitializeThread")
|
|
95
|
+
)?.[1];
|
|
96
|
+
if (!initialize) throw new Error("initializeThread activity not found");
|
|
97
|
+
|
|
98
|
+
await initialize("thread-1");
|
|
99
|
+
|
|
100
|
+
expect(redis.set).toHaveBeenCalledWith(metaKey, "1", { EX: 3600 });
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("defaults to THREAD_TTL_SECONDS when adapter ttlSeconds is omitted", async () => {
|
|
104
|
+
const redis = createMockRedis(retriedThread);
|
|
105
|
+
const client = createMockClient();
|
|
106
|
+
const adapter = createAnthropicAdapter({
|
|
107
|
+
redis: redis as never,
|
|
108
|
+
client: client as never,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
await adapter.createModelInvoker("claude-test")(invokerCall);
|
|
112
|
+
|
|
113
|
+
expect(redis.expire).toHaveBeenCalledWith(listKey, THREAD_TTL_SECONDS);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -57,9 +57,8 @@ export interface AnthropicAdapterConfig {
|
|
|
57
57
|
*/
|
|
58
58
|
coldStore?: ColdThreadStore;
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* is typically more appropriate.
|
|
60
|
+
* Redis TTL for the thread's keys; defaults to 90 days. Use a shorter
|
|
61
|
+
* value (hours) with a cold tier.
|
|
63
62
|
*/
|
|
64
63
|
ttlSeconds?: number;
|
|
65
64
|
}
|
|
@@ -160,32 +159,26 @@ export function createAnthropicAdapter(
|
|
|
160
159
|
): AnthropicAdapter {
|
|
161
160
|
const { redis, client } = config;
|
|
162
161
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
* `coldStore` / `ttlSeconds` configuration controls every Redis
|
|
168
|
-
* write the adapter does.
|
|
169
|
-
*/
|
|
170
|
-
const baseExtras = {
|
|
162
|
+
// Single source for the adapter's `redis` handle and configured TTL, spread
|
|
163
|
+
// into every internal thread manager so all of them share one configuration.
|
|
164
|
+
const base = {
|
|
165
|
+
redis,
|
|
171
166
|
...(config.ttlSeconds !== undefined && { ttlSeconds: config.ttlSeconds }),
|
|
172
167
|
};
|
|
173
168
|
|
|
174
169
|
const makeProviderThread = (threadId: string, threadKey?: string) =>
|
|
175
170
|
createAnthropicThreadManager({
|
|
176
|
-
|
|
171
|
+
...base,
|
|
177
172
|
threadId,
|
|
178
173
|
key: threadKey,
|
|
179
|
-
...baseExtras,
|
|
180
174
|
});
|
|
181
175
|
|
|
182
176
|
const makeTieredBase = (threadId: string, threadKey?: string) =>
|
|
183
177
|
createTieredThreadManager<StoredMessage>({
|
|
184
|
-
|
|
178
|
+
...base,
|
|
185
179
|
threadId,
|
|
186
180
|
key: threadKey,
|
|
187
181
|
idOf: storedMessageId,
|
|
188
|
-
...baseExtras,
|
|
189
182
|
...(config.coldStore && { coldStore: config.coldStore }),
|
|
190
183
|
});
|
|
191
184
|
|
|
@@ -240,11 +233,10 @@ export function createAnthropicAdapter(
|
|
|
240
233
|
threadKey?: string
|
|
241
234
|
): Promise<void> {
|
|
242
235
|
const thread = createAnthropicThreadManager({
|
|
243
|
-
|
|
236
|
+
...base,
|
|
244
237
|
threadId: sourceThreadId,
|
|
245
238
|
key: threadKey,
|
|
246
239
|
hooks: config.hooks,
|
|
247
|
-
...baseExtras,
|
|
248
240
|
});
|
|
249
241
|
await thread.fork(targetThreadId);
|
|
250
242
|
},
|
|
@@ -304,7 +296,7 @@ export function createAnthropicAdapter(
|
|
|
304
296
|
promptCache?: AnthropicPromptCacheConfig
|
|
305
297
|
): ModelInvoker<Anthropic.Messages.Message> => {
|
|
306
298
|
const invokerConfig: AnthropicModelInvokerConfig = {
|
|
307
|
-
|
|
299
|
+
...base,
|
|
308
300
|
client,
|
|
309
301
|
model,
|
|
310
302
|
...(maxTokens !== undefined ? { maxTokens } : {}),
|
|
@@ -2,6 +2,7 @@ import { describe, expect, it, vi } from "vitest";
|
|
|
2
2
|
import type Anthropic from "@anthropic-ai/sdk";
|
|
3
3
|
import { createAnthropicModelInvoker } from "./model-invoker";
|
|
4
4
|
import type { StoredMessage } from "./thread-manager";
|
|
5
|
+
import { THREAD_TTL_SECONDS } from "../../../lib/thread/keys";
|
|
5
6
|
|
|
6
7
|
function createMockRedis(stored: StoredMessage[]) {
|
|
7
8
|
return {
|
|
@@ -109,3 +110,52 @@ describe("createAnthropicModelInvoker prompt caching", () => {
|
|
|
109
110
|
expect(params?.messages[0]?.content).toBe("hello");
|
|
110
111
|
});
|
|
111
112
|
});
|
|
113
|
+
|
|
114
|
+
describe("createAnthropicModelInvoker thread TTL", () => {
|
|
115
|
+
// The tail message is stored under `assistant-1`, so the invoker's
|
|
116
|
+
// `truncateFromId(assistant-1)` trims it and re-stamps the surviving
|
|
117
|
+
// list key's TTL.
|
|
118
|
+
const retriedThread: StoredMessage[] = [
|
|
119
|
+
{ id: "msg-1", message: { role: "user", content: "hi" } },
|
|
120
|
+
{ id: "assistant-1", message: { role: "assistant", content: "prior" } },
|
|
121
|
+
];
|
|
122
|
+
const listKey = "messages:thread:thread-1";
|
|
123
|
+
const invokerConfig = {
|
|
124
|
+
threadId: "thread-1",
|
|
125
|
+
assistantMessageId: "assistant-1",
|
|
126
|
+
state: { tools: [] } as never,
|
|
127
|
+
agentName: "Agent",
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
it("re-stamps trimmed hot keys at the configured ttlSeconds", async () => {
|
|
131
|
+
const redis = createMockRedis(retriedThread);
|
|
132
|
+
const { client } = createMockClient();
|
|
133
|
+
const invoker = createAnthropicModelInvoker({
|
|
134
|
+
redis: redis as never,
|
|
135
|
+
client: client as never,
|
|
136
|
+
model: "claude-test",
|
|
137
|
+
ttlSeconds: 3600,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
await invoker(invokerConfig);
|
|
141
|
+
|
|
142
|
+
expect(redis.lTrim).toHaveBeenCalledWith(listKey, 0, 0);
|
|
143
|
+
expect(redis.expire).toHaveBeenCalledWith(listKey, 3600);
|
|
144
|
+
expect(redis.expire).not.toHaveBeenCalledWith(listKey, THREAD_TTL_SECONDS);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("defaults to THREAD_TTL_SECONDS when ttlSeconds is omitted", async () => {
|
|
148
|
+
const redis = createMockRedis(retriedThread);
|
|
149
|
+
const { client } = createMockClient();
|
|
150
|
+
const invoker = createAnthropicModelInvoker({
|
|
151
|
+
redis: redis as never,
|
|
152
|
+
client: client as never,
|
|
153
|
+
model: "claude-test",
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
await invoker(invokerConfig);
|
|
157
|
+
|
|
158
|
+
expect(redis.lTrim).toHaveBeenCalledWith(listKey, 0, 0);
|
|
159
|
+
expect(redis.expire).toHaveBeenCalledWith(listKey, THREAD_TTL_SECONDS);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -25,6 +25,11 @@ export interface AnthropicModelInvokerConfig {
|
|
|
25
25
|
*/
|
|
26
26
|
promptCache?: AnthropicPromptCacheConfig;
|
|
27
27
|
hooks?: AnthropicThreadManagerHooks;
|
|
28
|
+
/**
|
|
29
|
+
* Redis TTL for the thread's keys; defaults to 90 days. Use a shorter
|
|
30
|
+
* value (hours) with a cold tier.
|
|
31
|
+
*/
|
|
32
|
+
ttlSeconds?: number;
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
function toAnthropicTools(
|
|
@@ -68,6 +73,7 @@ export function createAnthropicModelInvoker({
|
|
|
68
73
|
maxTokens = 16384,
|
|
69
74
|
promptCache,
|
|
70
75
|
hooks,
|
|
76
|
+
ttlSeconds,
|
|
71
77
|
}: AnthropicModelInvokerConfig) {
|
|
72
78
|
return async function invokeAnthropicModel(
|
|
73
79
|
config: ModelInvokerConfig
|
|
@@ -80,6 +86,7 @@ export function createAnthropicModelInvoker({
|
|
|
80
86
|
threadId,
|
|
81
87
|
key: threadKey,
|
|
82
88
|
hooks,
|
|
89
|
+
...(ttlSeconds !== undefined && { ttlSeconds }),
|
|
83
90
|
});
|
|
84
91
|
// Truncate the thread starting at the id the assistant message
|
|
85
92
|
// will be stored under. On the happy path this is a no-op; on a
|
|
@@ -150,6 +157,7 @@ export async function invokeAnthropicModel({
|
|
|
150
157
|
maxTokens,
|
|
151
158
|
promptCache,
|
|
152
159
|
hooks,
|
|
160
|
+
ttlSeconds,
|
|
153
161
|
config,
|
|
154
162
|
}: {
|
|
155
163
|
redis: Redis;
|
|
@@ -158,6 +166,7 @@ export async function invokeAnthropicModel({
|
|
|
158
166
|
maxTokens?: number;
|
|
159
167
|
promptCache?: AnthropicPromptCacheConfig;
|
|
160
168
|
hooks?: AnthropicThreadManagerHooks;
|
|
169
|
+
ttlSeconds?: number;
|
|
161
170
|
config: ModelInvokerConfig;
|
|
162
171
|
}): Promise<AgentResponse<Anthropic.Messages.Message>> {
|
|
163
172
|
const invoker = createAnthropicModelInvoker({
|
|
@@ -167,6 +176,7 @@ export async function invokeAnthropicModel({
|
|
|
167
176
|
maxTokens,
|
|
168
177
|
promptCache,
|
|
169
178
|
hooks,
|
|
179
|
+
...(ttlSeconds !== undefined && { ttlSeconds }),
|
|
170
180
|
});
|
|
171
181
|
return invoker(config);
|
|
172
182
|
}
|
|
@@ -36,9 +36,8 @@ export interface AnthropicThreadManagerConfig {
|
|
|
36
36
|
key?: string;
|
|
37
37
|
hooks?: AnthropicThreadManagerHooks;
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* typically more appropriate.
|
|
39
|
+
* Redis TTL for the thread's keys; defaults to 90 days. Use a shorter
|
|
40
|
+
* value (hours) with a cold tier.
|
|
42
41
|
*/
|
|
43
42
|
ttlSeconds?: number;
|
|
44
43
|
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import type { GenerateContentResponse, Part } from "@google/genai";
|
|
3
|
+
import { createGoogleGenAIAdapter } from "./activities";
|
|
4
|
+
import type { StoredContent } from "./thread-manager";
|
|
5
|
+
import { THREAD_TTL_SECONDS } from "../../../lib/thread/keys";
|
|
6
|
+
|
|
7
|
+
function createMockRedis(stored: StoredContent[]) {
|
|
8
|
+
return {
|
|
9
|
+
exists: vi.fn().mockResolvedValue(1),
|
|
10
|
+
lRange: vi.fn().mockResolvedValue(stored.map((m) => JSON.stringify(m))),
|
|
11
|
+
lTrim: vi.fn().mockResolvedValue("OK"),
|
|
12
|
+
get: vi.fn().mockResolvedValue(null),
|
|
13
|
+
del: vi.fn().mockResolvedValue(1),
|
|
14
|
+
set: vi.fn().mockResolvedValue("OK"),
|
|
15
|
+
rPush: vi.fn().mockResolvedValue(1),
|
|
16
|
+
expire: vi.fn().mockResolvedValue(1),
|
|
17
|
+
eval: vi.fn().mockResolvedValue(1),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function createMockClient(parts: Part[] = [{ text: "ok" }]) {
|
|
22
|
+
const chunk: Partial<GenerateContentResponse> = {
|
|
23
|
+
candidates: [{ content: { role: "model", parts } }],
|
|
24
|
+
usageMetadata: { promptTokenCount: 10, candidatesTokenCount: 5 },
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
models: {
|
|
28
|
+
generateContentStream: vi.fn().mockResolvedValue({
|
|
29
|
+
async *[Symbol.asyncIterator]() {
|
|
30
|
+
yield chunk;
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
},
|
|
34
|
+
caches: {
|
|
35
|
+
create: vi.fn().mockResolvedValue({ name: "cached-content-ref" }),
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Tail stored under the `assistantMessageId`, so the invoker's
|
|
41
|
+
// `truncateFromId` trims it and re-stamps the surviving list key's TTL.
|
|
42
|
+
const retriedThread: StoredContent[] = [
|
|
43
|
+
{ id: "msg-1", content: { role: "user", parts: [{ text: "hi" }] } },
|
|
44
|
+
{ id: "assistant-1", content: { role: "model", parts: [{ text: "prior" }] } },
|
|
45
|
+
];
|
|
46
|
+
const listKey = "messages:thread:thread-1";
|
|
47
|
+
const metaKey = "messages:meta:thread:thread-1";
|
|
48
|
+
const invokerCall = {
|
|
49
|
+
threadId: "thread-1",
|
|
50
|
+
assistantMessageId: "assistant-1",
|
|
51
|
+
state: { tools: [] } as never,
|
|
52
|
+
agentName: "TestAgent",
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
describe("createGoogleGenAIAdapter — TTL propagation", () => {
|
|
56
|
+
it("forwards adapter ttlSeconds to a created invoker's writes", async () => {
|
|
57
|
+
const redis = createMockRedis(retriedThread);
|
|
58
|
+
const client = createMockClient();
|
|
59
|
+
const adapter = createGoogleGenAIAdapter({
|
|
60
|
+
redis: redis as never,
|
|
61
|
+
ttlSeconds: 3600,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
await adapter.createModelInvoker(
|
|
65
|
+
"gemini-2.5-flash",
|
|
66
|
+
client as never
|
|
67
|
+
)(invokerCall);
|
|
68
|
+
|
|
69
|
+
expect(redis.expire).toHaveBeenCalledWith(listKey, 3600);
|
|
70
|
+
expect(redis.expire).not.toHaveBeenCalledWith(listKey, THREAD_TTL_SECONDS);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("forwards adapter ttlSeconds to the default invoker", async () => {
|
|
74
|
+
const redis = createMockRedis(retriedThread);
|
|
75
|
+
const client = createMockClient();
|
|
76
|
+
const adapter = createGoogleGenAIAdapter({
|
|
77
|
+
redis: redis as never,
|
|
78
|
+
client: client as never,
|
|
79
|
+
model: "gemini-2.5-flash",
|
|
80
|
+
ttlSeconds: 3600,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
await adapter.invoker(invokerCall);
|
|
84
|
+
|
|
85
|
+
expect(redis.expire).toHaveBeenCalledWith(listKey, 3600);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("forwards adapter ttlSeconds to thread-op writes", async () => {
|
|
89
|
+
const redis = createMockRedis([]);
|
|
90
|
+
const adapter = createGoogleGenAIAdapter({
|
|
91
|
+
redis: redis as never,
|
|
92
|
+
ttlSeconds: 3600,
|
|
93
|
+
});
|
|
94
|
+
const acts = adapter.createActivities() as unknown as Record<
|
|
95
|
+
string,
|
|
96
|
+
(threadId: string, threadKey?: string) => Promise<void>
|
|
97
|
+
>;
|
|
98
|
+
const initialize = Object.entries(acts).find(([k]) =>
|
|
99
|
+
k.endsWith("InitializeThread")
|
|
100
|
+
)?.[1];
|
|
101
|
+
if (!initialize) throw new Error("initializeThread activity not found");
|
|
102
|
+
|
|
103
|
+
await initialize("thread-1");
|
|
104
|
+
|
|
105
|
+
expect(redis.set).toHaveBeenCalledWith(metaKey, "1", { EX: 3600 });
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("defaults to THREAD_TTL_SECONDS when adapter ttlSeconds is omitted", async () => {
|
|
109
|
+
const redis = createMockRedis(retriedThread);
|
|
110
|
+
const client = createMockClient();
|
|
111
|
+
const adapter = createGoogleGenAIAdapter({ redis: redis as never });
|
|
112
|
+
|
|
113
|
+
await adapter.createModelInvoker(
|
|
114
|
+
"gemini-2.5-flash",
|
|
115
|
+
client as never
|
|
116
|
+
)(invokerCall);
|
|
117
|
+
|
|
118
|
+
expect(redis.expire).toHaveBeenCalledWith(listKey, THREAD_TTL_SECONDS);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe("createGoogleGenAIAdapter — cache/config forwarding", () => {
|
|
123
|
+
it("forwards adapter cache config to the invoker", async () => {
|
|
124
|
+
const multiThread: StoredContent[] = [
|
|
125
|
+
{ id: "m1", content: { role: "user", parts: [{ text: "a" }] } },
|
|
126
|
+
{ id: "m2", content: { role: "model", parts: [{ text: "b" }] } },
|
|
127
|
+
{ id: "m3", content: { role: "user", parts: [{ text: "c" }] } },
|
|
128
|
+
];
|
|
129
|
+
const redis = createMockRedis(multiThread);
|
|
130
|
+
const client = createMockClient();
|
|
131
|
+
const adapter = createGoogleGenAIAdapter({
|
|
132
|
+
redis: redis as never,
|
|
133
|
+
cache: { splitIndex: 1 },
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
await adapter.createModelInvoker(
|
|
137
|
+
"gemini-2.5-flash",
|
|
138
|
+
client as never
|
|
139
|
+
)(invokerCall);
|
|
140
|
+
|
|
141
|
+
expect(client.caches.create).toHaveBeenCalledOnce();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("forwards adapter generationConfig to generateContentStream", async () => {
|
|
145
|
+
const redis = createMockRedis([
|
|
146
|
+
{ id: "m1", content: { role: "user", parts: [{ text: "a" }] } },
|
|
147
|
+
]);
|
|
148
|
+
const client = createMockClient();
|
|
149
|
+
const adapter = createGoogleGenAIAdapter({
|
|
150
|
+
redis: redis as never,
|
|
151
|
+
generationConfig: { temperature: 0.5 },
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
await adapter.createModelInvoker(
|
|
155
|
+
"gemini-2.5-flash",
|
|
156
|
+
client as never
|
|
157
|
+
)(invokerCall);
|
|
158
|
+
|
|
159
|
+
const streamCall = client.models.generateContentStream.mock.calls[0]?.[0];
|
|
160
|
+
expect(streamCall.config.temperature).toBe(0.5);
|
|
161
|
+
});
|
|
162
|
+
});
|