zeitlich 0.2.31 → 0.2.32
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/{activities-qPkJDAiq.d.cts → activities-DA-bQM12.d.cts} +2 -2
- package/dist/{activities-DRSdt8Y3.d.ts → activities-FIXVz7DT.d.ts} +2 -2
- package/dist/adapters/thread/anthropic/index.cjs +4 -48
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +6 -6
- package/dist/adapters/thread/anthropic/index.d.ts +6 -6
- package/dist/adapters/thread/anthropic/index.js +4 -48
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.cjs +1 -0
- package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +4 -4
- package/dist/adapters/thread/anthropic/workflow.d.ts +4 -4
- package/dist/adapters/thread/anthropic/workflow.js +1 -0
- package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.cjs +8 -48
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +6 -6
- package/dist/adapters/thread/google-genai/index.d.ts +6 -6
- package/dist/adapters/thread/google-genai/index.js +8 -48
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.cjs +1 -0
- package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +4 -4
- package/dist/adapters/thread/google-genai/workflow.d.ts +4 -4
- package/dist/adapters/thread/google-genai/workflow.js +1 -0
- package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
- package/dist/adapters/thread/langchain/index.cjs +5 -1
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +6 -5
- package/dist/adapters/thread/langchain/index.d.ts +6 -5
- package/dist/adapters/thread/langchain/index.js +5 -1
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.cjs +1 -0
- package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +4 -4
- package/dist/adapters/thread/langchain/workflow.d.ts +4 -4
- package/dist/adapters/thread/langchain/workflow.js +1 -0
- package/dist/adapters/thread/langchain/workflow.js.map +1 -1
- package/dist/index.cjs +8 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/{proxy-BkvkV2oU.d.ts → proxy-Br4unLTC.d.ts} +1 -1
- package/dist/{proxy-BDQ3Rj6R.d.cts → proxy-CTCYWjkr.d.cts} +1 -1
- package/dist/{thread-manager-BLgvv9Gf.d.cts → thread-manager-CUubPYPH.d.cts} +1 -1
- package/dist/{thread-manager-DowU4ntB.d.cts → thread-manager-Cv_BR28i.d.cts} +1 -1
- package/dist/{thread-manager-Cv82H1wi.d.ts → thread-manager-DKWxHUzD.d.ts} +1 -1
- package/dist/{thread-manager-HsAYkyAV.d.ts → thread-manager-YJLoc1vH.d.ts} +1 -1
- package/dist/{types-CjeGWQm1.d.cts → types-Bpq5fDI5.d.cts} +7 -4
- package/dist/{types-D6UKZZtj.d.ts → types-BxiT8w9d.d.ts} +1 -1
- package/dist/{types-BmS-Huc0.d.ts → types-CheCTLeV.d.ts} +7 -4
- package/dist/{types-e_38QaKo.d.cts → types-NJDyMyUx.d.cts} +1 -1
- package/dist/{workflow-CNshfqSO.d.cts → workflow-BWKQcz9d.d.cts} +1 -1
- package/dist/{workflow-CTcrPZAV.d.ts → workflow-D8wK7TJY.d.ts} +1 -1
- package/dist/workflow.cjs +4 -1
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +2 -2
- package/dist/workflow.d.ts +2 -2
- package/dist/workflow.js +4 -1
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/thread/anthropic/activities.ts +10 -0
- package/src/adapters/thread/anthropic/model-invoker.ts +2 -5
- package/src/adapters/thread/google-genai/activities.ts +14 -0
- package/src/adapters/thread/google-genai/model-invoker.ts +2 -5
- package/src/adapters/thread/langchain/activities.ts +11 -0
- package/src/adapters/thread/langchain/model-invoker.ts +2 -3
- package/src/lib/.env +1 -0
- package/src/lib/model/types.ts +3 -2
- package/src/lib/session/session-edge-cases.integration.test.ts +6 -0
- package/src/lib/session/session.integration.test.ts +3 -0
- package/src/lib/session/session.ts +4 -0
- package/src/lib/session/types.ts +7 -0
- package/src/lib/thread/proxy.ts +1 -0
- package/src/lib/types.ts +1 -0
- package/src/lib/virtual-fs/manager.ts +3 -3
- package/src/lib/virtual-fs/proxy.ts +3 -3
- package/src/lib/virtual-fs/types.ts +1 -2
- package/src/lib/virtual-fs/with-virtual-fs.ts +4 -4
- package/src/tools/bash/.env +1 -0
package/package.json
CHANGED
|
@@ -164,6 +164,16 @@ export function createAnthropicAdapter(
|
|
|
164
164
|
await thread.appendToolResult(id, toolCallId, toolName, content);
|
|
165
165
|
},
|
|
166
166
|
|
|
167
|
+
async appendAgentMessage(
|
|
168
|
+
threadId: string,
|
|
169
|
+
id: string,
|
|
170
|
+
message: Anthropic.Messages.Message,
|
|
171
|
+
threadKey?: string,
|
|
172
|
+
): Promise<void> {
|
|
173
|
+
const thread = createAnthropicThreadManager({ redis, threadId, key: threadKey });
|
|
174
|
+
await thread.appendAssistantMessage(id, message.content);
|
|
175
|
+
},
|
|
176
|
+
|
|
167
177
|
async forkThread(
|
|
168
178
|
sourceThreadId: string,
|
|
169
179
|
targetThreadId: string,
|
|
@@ -3,7 +3,6 @@ import type Anthropic from "@anthropic-ai/sdk";
|
|
|
3
3
|
import type { SerializableToolDefinition } from "../../../lib/types";
|
|
4
4
|
import type { AgentResponse, ModelInvokerConfig } from "../../../lib/model";
|
|
5
5
|
import { createAnthropicThreadManager, type AnthropicThreadManagerHooks } from "./thread-manager";
|
|
6
|
-
import { v4 as uuidv4 } from "uuid";
|
|
7
6
|
|
|
8
7
|
export interface AnthropicModelInvokerConfig {
|
|
9
8
|
redis: Redis;
|
|
@@ -29,8 +28,8 @@ function toAnthropicTools(
|
|
|
29
28
|
* `ModelInvoker<Anthropic.Messages.Message>` contract.
|
|
30
29
|
*
|
|
31
30
|
* Loads the conversation thread from Redis, invokes the Claude model via
|
|
32
|
-
* `client.messages.create`,
|
|
33
|
-
*
|
|
31
|
+
* `client.messages.create`, and returns a normalised AgentResponse.
|
|
32
|
+
* The caller is responsible for appending the response to the thread.
|
|
34
33
|
*
|
|
35
34
|
* @example
|
|
36
35
|
* ```typescript
|
|
@@ -74,8 +73,6 @@ export function createAnthropicModelInvoker({
|
|
|
74
73
|
...(tools ? { tools } : {}),
|
|
75
74
|
});
|
|
76
75
|
|
|
77
|
-
await thread.appendAssistantMessage(uuidv4(), response.content);
|
|
78
|
-
|
|
79
76
|
const toolCalls = response.content.filter(
|
|
80
77
|
(block): block is Anthropic.Messages.ToolUseBlock =>
|
|
81
78
|
block.type === "tool_use",
|
|
@@ -194,6 +194,20 @@ export function createGoogleGenAIAdapter(
|
|
|
194
194
|
);
|
|
195
195
|
},
|
|
196
196
|
|
|
197
|
+
async appendAgentMessage(
|
|
198
|
+
threadId: string,
|
|
199
|
+
id: string,
|
|
200
|
+
message: Content,
|
|
201
|
+
threadKey?: string,
|
|
202
|
+
): Promise<void> {
|
|
203
|
+
const thread = createGoogleGenAIThreadManager({
|
|
204
|
+
redis,
|
|
205
|
+
threadId,
|
|
206
|
+
key: threadKey,
|
|
207
|
+
});
|
|
208
|
+
await thread.appendModelContent(id, message.parts ?? []);
|
|
209
|
+
},
|
|
210
|
+
|
|
197
211
|
async forkThread(
|
|
198
212
|
sourceThreadId: string,
|
|
199
213
|
targetThreadId: string,
|
|
@@ -3,7 +3,6 @@ import type { GoogleGenAI, Content, FunctionDeclaration } from "@google/genai";
|
|
|
3
3
|
import type { SerializableToolDefinition } from "../../../lib/types";
|
|
4
4
|
import type { AgentResponse, ModelInvokerConfig } from "../../../lib/model";
|
|
5
5
|
import { createGoogleGenAIThreadManager, type GoogleGenAIThreadManagerHooks } from "./thread-manager";
|
|
6
|
-
import { v4 as uuidv4 } from "uuid";
|
|
7
6
|
|
|
8
7
|
export interface GoogleGenAIModelInvokerConfig {
|
|
9
8
|
redis: Redis;
|
|
@@ -27,8 +26,8 @@ function toFunctionDeclarations(
|
|
|
27
26
|
* `ModelInvoker<Content>` contract.
|
|
28
27
|
*
|
|
29
28
|
* Loads the conversation thread from Redis, invokes the Gemini model via
|
|
30
|
-
* `client.models.generateContent`,
|
|
31
|
-
*
|
|
29
|
+
* `client.models.generateContent`, and returns a normalised AgentResponse.
|
|
30
|
+
* The caller is responsible for appending the response to the thread.
|
|
32
31
|
*
|
|
33
32
|
* @example
|
|
34
33
|
* ```typescript
|
|
@@ -77,8 +76,6 @@ export function createGoogleGenAIModelInvoker({
|
|
|
77
76
|
const responseParts = response.candidates?.[0]?.content?.parts ?? [];
|
|
78
77
|
const modelContent: Content = { role: "model", parts: responseParts };
|
|
79
78
|
|
|
80
|
-
await thread.appendModelContent(uuidv4(), responseParts);
|
|
81
|
-
|
|
82
79
|
const functionCalls = response.functionCalls ?? [];
|
|
83
80
|
|
|
84
81
|
return {
|
|
@@ -148,6 +148,17 @@ export function createLangChainAdapter(
|
|
|
148
148
|
await thread.appendToolResult(id, toolCallId, "", content);
|
|
149
149
|
},
|
|
150
150
|
|
|
151
|
+
async appendAgentMessage(
|
|
152
|
+
threadId: string,
|
|
153
|
+
id: string,
|
|
154
|
+
message: StoredMessage,
|
|
155
|
+
threadKey?: string,
|
|
156
|
+
): Promise<void> {
|
|
157
|
+
const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });
|
|
158
|
+
const patched = { ...message, data: { ...message.data, id } };
|
|
159
|
+
await thread.append([patched]);
|
|
160
|
+
},
|
|
161
|
+
|
|
151
162
|
async forkThread(
|
|
152
163
|
sourceThreadId: string,
|
|
153
164
|
targetThreadId: string,
|
|
@@ -17,7 +17,8 @@ export interface LangChainModelInvokerConfig<TModel extends BaseChatModel<any> =
|
|
|
17
17
|
* `ModelInvoker<StoredMessage>` contract.
|
|
18
18
|
*
|
|
19
19
|
* Loads the conversation thread from Redis, invokes a LangChain chat model,
|
|
20
|
-
*
|
|
20
|
+
* and returns a normalised AgentResponse.
|
|
21
|
+
* The caller is responsible for appending the response to the thread.
|
|
21
22
|
*
|
|
22
23
|
* @example
|
|
23
24
|
* ```typescript
|
|
@@ -54,8 +55,6 @@ export function createLangChainModelInvoker<TModel extends BaseChatModel<any> =
|
|
|
54
55
|
},
|
|
55
56
|
);
|
|
56
57
|
|
|
57
|
-
await thread.append([response.toDict()]);
|
|
58
|
-
|
|
59
58
|
const toolCalls = response.tool_calls ?? [];
|
|
60
59
|
|
|
61
60
|
return {
|
package/src/lib/.env
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
E2B_API_KEY=e2b_39af116424059782e2aee6942fd70237cc2126c9
|
package/src/lib/model/types.ts
CHANGED
|
@@ -33,8 +33,9 @@ export interface ModelInvokerConfig {
|
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Generic model invocation contract.
|
|
36
|
-
* Implementations load the thread, call the LLM,
|
|
37
|
-
*
|
|
36
|
+
* Implementations load the thread, call the LLM, and return a normalised
|
|
37
|
+
* AgentResponse. The caller (workflow) is responsible for appending the
|
|
38
|
+
* response to the thread with a deterministic ID.
|
|
38
39
|
*
|
|
39
40
|
* Framework adapters (e.g. `zeitlich/langchain`) provide concrete
|
|
40
41
|
* implementations of this type.
|
|
@@ -88,6 +88,9 @@ function createMockThreadOps() {
|
|
|
88
88
|
appendSystemMessage: async (threadId, id, content) => {
|
|
89
89
|
log.push({ op: "appendSystemMessage", args: [threadId, id, content] });
|
|
90
90
|
},
|
|
91
|
+
appendAgentMessage: async (threadId, id, message) => {
|
|
92
|
+
log.push({ op: "appendAgentMessage", args: [threadId, id, message] });
|
|
93
|
+
},
|
|
91
94
|
forkThread: async (source, target) => {
|
|
92
95
|
log.push({ op: "forkThread", args: [source, target] });
|
|
93
96
|
},
|
|
@@ -752,6 +755,9 @@ describe("createSession edge cases", () => {
|
|
|
752
755
|
appendSystemMessage: async (threadId, id, content) => {
|
|
753
756
|
log.push({ op: "appendSystemMessage", args: [threadId, id, content] });
|
|
754
757
|
},
|
|
758
|
+
appendAgentMessage: async (threadId, id, message) => {
|
|
759
|
+
log.push({ op: "appendAgentMessage", args: [threadId, id, message] });
|
|
760
|
+
},
|
|
755
761
|
forkThread: async (source, target) => {
|
|
756
762
|
log.push({ op: "forkThread", args: [source, target] });
|
|
757
763
|
},
|
|
@@ -99,6 +99,9 @@ function createMockThreadOps() {
|
|
|
99
99
|
appendSystemMessage: async (threadId, id, content) => {
|
|
100
100
|
log.push({ op: "appendSystemMessage", args: [threadId, id, content] });
|
|
101
101
|
},
|
|
102
|
+
appendAgentMessage: async (threadId, id, message) => {
|
|
103
|
+
log.push({ op: "appendAgentMessage", args: [threadId, id, message] });
|
|
104
|
+
},
|
|
102
105
|
forkThread: async (source, target) => {
|
|
103
106
|
log.push({ op: "forkThread", args: [source, target] });
|
|
104
107
|
},
|
|
@@ -139,6 +139,7 @@ export async function createSession<
|
|
|
139
139
|
appendHumanMessage,
|
|
140
140
|
initializeThread,
|
|
141
141
|
appendSystemMessage,
|
|
142
|
+
appendAgentMessage,
|
|
142
143
|
forkThread,
|
|
143
144
|
} = threadOps;
|
|
144
145
|
|
|
@@ -285,6 +286,7 @@ export async function createSession<
|
|
|
285
286
|
: result.fileTree;
|
|
286
287
|
stateManager.mergeUpdate({
|
|
287
288
|
fileTree,
|
|
289
|
+
virtualFsCtx: virtualFsConfig.ctx,
|
|
288
290
|
...(skillFiles && { inlineFiles: skillFiles }),
|
|
289
291
|
} as Partial<AgentState<TState>>);
|
|
290
292
|
}
|
|
@@ -355,6 +357,8 @@ export async function createSession<
|
|
|
355
357
|
metadata,
|
|
356
358
|
});
|
|
357
359
|
|
|
360
|
+
await appendAgentMessage(threadId, uuid4(), message, threadKey);
|
|
361
|
+
|
|
358
362
|
if (usage) {
|
|
359
363
|
stateManager.updateUsage(usage);
|
|
360
364
|
}
|
package/src/lib/session/types.ts
CHANGED
|
@@ -39,6 +39,13 @@ export interface ThreadOps<TContent = string> {
|
|
|
39
39
|
): Promise<void>;
|
|
40
40
|
/** Append a tool result to the thread */
|
|
41
41
|
appendToolResult(id: string, config: ToolResultConfig): Promise<void>;
|
|
42
|
+
/** Append the model's response to the thread */
|
|
43
|
+
appendAgentMessage(
|
|
44
|
+
threadId: string,
|
|
45
|
+
id: string,
|
|
46
|
+
message: unknown,
|
|
47
|
+
threadKey?: string
|
|
48
|
+
): Promise<void>;
|
|
42
49
|
/** Append a system message to the thread */
|
|
43
50
|
appendSystemMessage(
|
|
44
51
|
threadId: string,
|
package/src/lib/thread/proxy.ts
CHANGED
|
@@ -51,6 +51,7 @@ export function createThreadOpsProxy(
|
|
|
51
51
|
initializeThread: acts[p("initializeThread")],
|
|
52
52
|
appendHumanMessage: acts[p("appendHumanMessage")],
|
|
53
53
|
appendToolResult: acts[p("appendToolResult")],
|
|
54
|
+
appendAgentMessage: acts[p("appendAgentMessage")],
|
|
54
55
|
appendSystemMessage: acts[p("appendSystemMessage")],
|
|
55
56
|
forkThread: acts[p("forkThread")],
|
|
56
57
|
} as ActivityInterfaceFor<ThreadOps>;
|
package/src/lib/types.ts
CHANGED
|
@@ -27,6 +27,7 @@ export interface BaseAgentState {
|
|
|
27
27
|
fileTree: FileEntry[];
|
|
28
28
|
/** In-memory file contents keyed by path, bypassing the resolver (e.g. skill resources). */
|
|
29
29
|
inlineFiles?: Record<string, string>;
|
|
30
|
+
virtualFsCtx?: unknown;
|
|
30
31
|
systemPrompt?: string;
|
|
31
32
|
totalInputTokens: number;
|
|
32
33
|
totalOutputTokens: number;
|
|
@@ -30,7 +30,7 @@ export function createVirtualFsActivities<
|
|
|
30
30
|
TMeta = FileEntryMetadata,
|
|
31
31
|
>(
|
|
32
32
|
resolver: FileResolver<TCtx, TMeta>,
|
|
33
|
-
scope: S
|
|
33
|
+
scope: S
|
|
34
34
|
): PrefixedVirtualFsOps<S, TCtx, TMeta> {
|
|
35
35
|
const ops: VirtualFsOps<TCtx, TMeta> = {
|
|
36
36
|
resolveFileTree: async (ctx: TCtx) => {
|
|
@@ -39,10 +39,10 @@ export function createVirtualFsActivities<
|
|
|
39
39
|
},
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const prefix = scope
|
|
42
|
+
const prefix = `virtualFs${scope.charAt(0).toUpperCase()}${scope.slice(1)}`;
|
|
43
43
|
const cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);
|
|
44
44
|
|
|
45
45
|
return Object.fromEntries(
|
|
46
|
-
Object.entries(ops).map(([k, v]) => [`${prefix}${cap(k)}`, v])
|
|
46
|
+
Object.entries(ops).map(([k, v]) => [`${prefix}${cap(k)}`, v])
|
|
47
47
|
) as PrefixedVirtualFsOps<S, TCtx, TMeta>;
|
|
48
48
|
}
|
|
@@ -18,7 +18,7 @@ import type { VirtualFsOps } from "./types";
|
|
|
18
18
|
|
|
19
19
|
export function proxyVirtualFsOps<TCtx = unknown>(
|
|
20
20
|
scope?: string,
|
|
21
|
-
options?: Parameters<typeof proxyActivities>[0]
|
|
21
|
+
options?: Parameters<typeof proxyActivities>[0]
|
|
22
22
|
): VirtualFsOps<TCtx> {
|
|
23
23
|
const resolvedScope = scope ?? workflowInfo().workflowType;
|
|
24
24
|
|
|
@@ -32,10 +32,10 @@ export function proxyVirtualFsOps<TCtx = unknown>(
|
|
|
32
32
|
maximumInterval: "30s",
|
|
33
33
|
backoffCoefficient: 2,
|
|
34
34
|
},
|
|
35
|
-
}
|
|
35
|
+
}
|
|
36
36
|
);
|
|
37
37
|
|
|
38
|
-
const prefix = resolvedScope
|
|
38
|
+
const prefix = `virtualFs${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;
|
|
39
39
|
const p = (key: string): string =>
|
|
40
40
|
`${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
41
41
|
|
|
@@ -118,8 +118,7 @@ export type PrefixedVirtualFsOps<
|
|
|
118
118
|
*/
|
|
119
119
|
export interface VirtualFsState<TCtx = unknown, TMeta = FileEntryMetadata> {
|
|
120
120
|
fileTree: FileEntry<TMeta>[];
|
|
121
|
-
|
|
122
|
-
workspaceBase?: string;
|
|
121
|
+
virtualFsCtx: TCtx;
|
|
123
122
|
/** In-memory file contents keyed by path, bypassing the resolver (e.g. skill resources). */
|
|
124
123
|
inlineFiles?: Record<string, string>;
|
|
125
124
|
}
|
|
@@ -66,7 +66,7 @@ export function withVirtualFs<
|
|
|
66
66
|
const state =
|
|
67
67
|
await queryParentWorkflowState<VirtualFsState<TCtx, TMeta>>(client);
|
|
68
68
|
|
|
69
|
-
const { fileTree,
|
|
69
|
+
const { fileTree, virtualFsCtx, inlineFiles } = state;
|
|
70
70
|
if (!fileTree) {
|
|
71
71
|
return {
|
|
72
72
|
toolResponse: `Error: No fileTree in agent state. The ${context.toolName} tool requires a virtual filesystem.`,
|
|
@@ -77,9 +77,9 @@ export function withVirtualFs<
|
|
|
77
77
|
const virtualFs = new VirtualFileSystem(
|
|
78
78
|
fileTree,
|
|
79
79
|
resolver,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
inlineFiles
|
|
80
|
+
virtualFsCtx,
|
|
81
|
+
"/",
|
|
82
|
+
inlineFiles
|
|
83
83
|
);
|
|
84
84
|
const response = await handler(args, { ...context, virtualFs });
|
|
85
85
|
const mutations = virtualFs.getMutations();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
E2B_API_KEY=e2b_39af116424059782e2aee6942fd70237cc2126c9
|