zeitlich 0.2.11 → 0.2.13
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/README.md +313 -126
- package/dist/adapters/langchain/index.cjs +270 -0
- package/dist/adapters/langchain/index.cjs.map +1 -0
- package/dist/adapters/langchain/index.d.cts +132 -0
- package/dist/adapters/langchain/index.d.ts +132 -0
- package/dist/adapters/langchain/index.js +265 -0
- package/dist/adapters/langchain/index.js.map +1 -0
- package/dist/index.cjs +89 -209
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -46
- package/dist/index.d.ts +62 -46
- package/dist/index.js +88 -208
- package/dist/index.js.map +1 -1
- package/dist/{workflow-BhjsEQc1.d.cts → model-invoker-y_zlyMqu.d.cts} +45 -482
- package/dist/{workflow-BhjsEQc1.d.ts → model-invoker-y_zlyMqu.d.ts} +45 -482
- package/dist/thread-manager-qc0g5Rvd.d.cts +39 -0
- package/dist/thread-manager-qc0g5Rvd.d.ts +39 -0
- package/dist/workflow.cjs +59 -27
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +459 -6
- package/dist/workflow.d.ts +459 -6
- package/dist/workflow.js +60 -29
- package/dist/workflow.js.map +1 -1
- package/package.json +17 -2
- package/src/adapters/langchain/activities.ts +120 -0
- package/src/adapters/langchain/index.ts +38 -0
- package/src/adapters/langchain/model-invoker.ts +102 -0
- package/src/adapters/langchain/thread-manager.ts +142 -0
- package/src/index.ts +24 -23
- package/src/lib/fs.ts +25 -0
- package/src/lib/model-invoker.ts +15 -75
- package/src/lib/session.ts +52 -21
- package/src/lib/state-manager.ts +23 -5
- package/src/lib/thread-id.ts +25 -0
- package/src/lib/thread-manager.ts +18 -142
- package/src/lib/tool-router.ts +12 -18
- package/src/lib/types.ts +26 -10
- package/src/lib/workflow-helpers.ts +50 -0
- package/src/tools/ask-user-question/handler.ts +25 -1
- package/src/tools/bash/handler.ts +13 -0
- package/src/tools/subagent/handler.ts +16 -5
- package/src/tools/subagent/tool.ts +34 -15
- package/src/workflow.ts +26 -7
- package/tsup.config.ts +1 -0
- package/src/activities.ts +0 -91
- package/src/plugin.ts +0 -28
|
@@ -11,6 +11,19 @@ type BashExecOut = {
|
|
|
11
11
|
/** BashOptions with `fs` required */
|
|
12
12
|
type BashToolOptions = Required<Pick<BashOptions, "fs">> & Omit<BashOptions, "fs">;
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Creates a Bash tool handler that executes shell commands in a sandboxed environment.
|
|
16
|
+
*
|
|
17
|
+
* @param bashOptions - Options including a required `fs` (file system implementation from `just-bash`)
|
|
18
|
+
* @returns Activity tool handler for Bash tool calls
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import { createBashHandler } from 'zeitlich';
|
|
23
|
+
*
|
|
24
|
+
* const bashHandlerActivity = createBashHandler({ fs: inMemoryFileSystem });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
14
27
|
export const createBashHandler: (
|
|
15
28
|
bashOptions: BashToolOptions,
|
|
16
29
|
) => ActivityToolHandler<BashArgs, BashExecOut | null> =
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { executeChild, workflowInfo
|
|
1
|
+
import { executeChild, workflowInfo } from "@temporalio/workflow";
|
|
2
|
+
import { getShortId } from "../../lib/thread-id";
|
|
2
3
|
import type { ToolHandlerResponse } from "../../lib/tool-router";
|
|
4
|
+
import type { ToolMessageContent } from "../../lib/types";
|
|
3
5
|
import type {
|
|
4
6
|
InferSubagentResult,
|
|
5
7
|
SubagentConfig,
|
|
@@ -40,12 +42,13 @@ export function createSubagentHandler<
|
|
|
40
42
|
);
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
const childWorkflowId = `${args.subagent}-${
|
|
45
|
+
const childWorkflowId = `${args.subagent}-${getShortId()}`;
|
|
44
46
|
|
|
45
|
-
// Execute the child workflow
|
|
46
47
|
const input: SubagentInput = {
|
|
47
48
|
prompt: args.prompt,
|
|
48
49
|
...(config.context && { context: config.context }),
|
|
50
|
+
...(args.threadId &&
|
|
51
|
+
config.allowThreadContinuation && { threadId: args.threadId }),
|
|
49
52
|
};
|
|
50
53
|
|
|
51
54
|
const childOpts = {
|
|
@@ -54,7 +57,7 @@ export function createSubagentHandler<
|
|
|
54
57
|
taskQueue: config.taskQueue ?? parentTaskQueue,
|
|
55
58
|
};
|
|
56
59
|
|
|
57
|
-
const { toolResponse, data, usage } =
|
|
60
|
+
const { toolResponse, data, usage, threadId: childThreadId } =
|
|
58
61
|
typeof config.workflow === "string"
|
|
59
62
|
? await executeChild(config.workflow, childOpts)
|
|
60
63
|
: await executeChild(config.workflow, childOpts);
|
|
@@ -80,8 +83,16 @@ export function createSubagentHandler<
|
|
|
80
83
|
};
|
|
81
84
|
}
|
|
82
85
|
|
|
86
|
+
let finalToolResponse: ToolMessageContent = toolResponse;
|
|
87
|
+
if (config.allowThreadContinuation && childThreadId) {
|
|
88
|
+
finalToolResponse =
|
|
89
|
+
typeof toolResponse === "string"
|
|
90
|
+
? `${toolResponse}\n\n[Thread ID: ${childThreadId}]`
|
|
91
|
+
: toolResponse;
|
|
92
|
+
}
|
|
93
|
+
|
|
83
94
|
return {
|
|
84
|
-
toolResponse,
|
|
95
|
+
toolResponse: finalToolResponse,
|
|
85
96
|
data: validated ? validated.data : data,
|
|
86
97
|
...(usage && { usage }),
|
|
87
98
|
};
|
|
@@ -8,7 +8,12 @@ export const SUBAGENT_TOOL_NAME = "Subagent" as const;
|
|
|
8
8
|
*/
|
|
9
9
|
function buildSubagentDescription(subagents: SubagentConfig[]): string {
|
|
10
10
|
const subagentList = subagents
|
|
11
|
-
.map((s) =>
|
|
11
|
+
.map((s) => {
|
|
12
|
+
const continuation = s.allowThreadContinuation
|
|
13
|
+
? "\n*(Supports thread continuation — pass a threadId to resume a previous conversation)*"
|
|
14
|
+
: "";
|
|
15
|
+
return `## ${s.agentName}\n${s.description}${continuation}`;
|
|
16
|
+
})
|
|
12
17
|
.join("\n\n");
|
|
13
18
|
|
|
14
19
|
return `The ${SUBAGENT_TOOL_NAME} tool launches specialized agents (subagents) that autonomously handle complex work. Each agent type has specific capabilities and tools available to it.
|
|
@@ -37,30 +42,43 @@ ${subagentList}
|
|
|
37
42
|
export function createSubagentTool<T extends SubagentConfig[]>(
|
|
38
43
|
subagents: T
|
|
39
44
|
): {
|
|
40
|
-
name:
|
|
41
|
-
description: string;
|
|
42
|
-
schema: z.ZodObject<
|
|
43
|
-
subagent: z.ZodEnum<Record<string, string>>;
|
|
44
|
-
description: z.ZodString;
|
|
45
|
-
prompt: z.ZodString;
|
|
46
|
-
}>;
|
|
45
|
+
readonly name: typeof SUBAGENT_TOOL_NAME;
|
|
46
|
+
readonly description: string;
|
|
47
|
+
readonly schema: z.ZodObject<z.ZodRawShape>;
|
|
47
48
|
} {
|
|
48
49
|
if (subagents.length === 0) {
|
|
49
50
|
throw new Error("createTaskTool requires at least one subagent");
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
const names = subagents.map((s) => s.agentName);
|
|
54
|
+
const hasThreadContinuation = subagents.some(
|
|
55
|
+
(s) => s.allowThreadContinuation
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const baseFields = {
|
|
59
|
+
subagent: z.enum(names).describe("The type of subagent to launch"),
|
|
60
|
+
description: z
|
|
61
|
+
.string()
|
|
62
|
+
.describe("A short (3-5 word) description of the task"),
|
|
63
|
+
prompt: z.string().describe("The task for the agent to perform"),
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const schema = hasThreadContinuation
|
|
67
|
+
? z.object({
|
|
68
|
+
...baseFields,
|
|
69
|
+
threadId: z
|
|
70
|
+
.string()
|
|
71
|
+
.nullable()
|
|
72
|
+
.describe(
|
|
73
|
+
"Thread ID to continue an existing conversation, or null to start a new one"
|
|
74
|
+
),
|
|
75
|
+
})
|
|
76
|
+
: z.object(baseFields);
|
|
53
77
|
|
|
54
78
|
return {
|
|
55
79
|
name: SUBAGENT_TOOL_NAME,
|
|
56
80
|
description: buildSubagentDescription(subagents),
|
|
57
|
-
schema
|
|
58
|
-
subagent: z.enum(names).describe("The type of subagent to launch"),
|
|
59
|
-
description: z
|
|
60
|
-
.string()
|
|
61
|
-
.describe("A short (3-5 word) description of the task"),
|
|
62
|
-
prompt: z.string().describe("The task for the agent to perform"),
|
|
63
|
-
}),
|
|
81
|
+
schema,
|
|
64
82
|
} as const;
|
|
65
83
|
}
|
|
66
84
|
|
|
@@ -71,4 +89,5 @@ export type SubagentArgs = {
|
|
|
71
89
|
subagent: string;
|
|
72
90
|
description: string;
|
|
73
91
|
prompt: string;
|
|
92
|
+
threadId?: string;
|
|
74
93
|
};
|
package/src/workflow.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow-safe exports for use in Temporal workflow code.
|
|
3
3
|
*
|
|
4
|
-
* Import from
|
|
4
|
+
* Import from `zeitlich/workflow` in workflow files.
|
|
5
5
|
* These exports have no external dependencies (no Redis, no LangChain).
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
@@ -10,13 +10,19 @@
|
|
|
10
10
|
* import {
|
|
11
11
|
* createSession,
|
|
12
12
|
* createAgentStateManager,
|
|
13
|
-
*
|
|
13
|
+
* askUserQuestionTool,
|
|
14
|
+
* bashTool,
|
|
15
|
+
* defineTool,
|
|
16
|
+
* type SubagentWorkflow,
|
|
14
17
|
* } from 'zeitlich/workflow';
|
|
15
18
|
* ```
|
|
16
19
|
*/
|
|
17
20
|
|
|
18
21
|
// Session
|
|
19
22
|
export { createSession, proxyDefaultThreadOps } from "./lib/session";
|
|
23
|
+
|
|
24
|
+
// Thread utilities
|
|
25
|
+
export { getShortId } from "./lib/thread-id";
|
|
20
26
|
export type { ZeitlichSession, SessionLifecycleHooks } from "./lib/session";
|
|
21
27
|
|
|
22
28
|
// State management
|
|
@@ -59,23 +65,30 @@ export type {
|
|
|
59
65
|
ToolCallResultUnion,
|
|
60
66
|
InferToolResults,
|
|
61
67
|
// Other
|
|
62
|
-
ToolMessageContent,
|
|
63
68
|
AppendToolResultFn,
|
|
64
69
|
ProcessToolCallsContext,
|
|
65
70
|
} from "./lib/tool-router";
|
|
66
71
|
|
|
67
72
|
// Types
|
|
68
73
|
export type {
|
|
74
|
+
// Message types (framework-agnostic)
|
|
75
|
+
ContentPart,
|
|
76
|
+
MessageContent,
|
|
77
|
+
ToolMessageContent,
|
|
78
|
+
TokenUsage,
|
|
79
|
+
// Agent types
|
|
69
80
|
AgentStatus,
|
|
70
81
|
BaseAgentState,
|
|
71
82
|
AgentFile,
|
|
72
83
|
AgentResponse,
|
|
73
84
|
ThreadOps,
|
|
74
85
|
AgentConfig,
|
|
86
|
+
SessionConfig,
|
|
75
87
|
RunAgentConfig,
|
|
76
88
|
RunAgentActivity,
|
|
77
89
|
ToolResultConfig,
|
|
78
90
|
SessionExitReason,
|
|
91
|
+
// Hook types
|
|
79
92
|
PreToolUseHook,
|
|
80
93
|
PreToolUseHookContext,
|
|
81
94
|
PreToolUseHookResult,
|
|
@@ -84,14 +97,21 @@ export type {
|
|
|
84
97
|
PostToolUseFailureHook,
|
|
85
98
|
PostToolUseFailureHookContext,
|
|
86
99
|
PostToolUseFailureHookResult,
|
|
100
|
+
PreHumanMessageAppendHook,
|
|
101
|
+
PreHumanMessageAppendHookContext,
|
|
102
|
+
PostHumanMessageAppendHook,
|
|
103
|
+
PostHumanMessageAppendHookContext,
|
|
104
|
+
Hooks,
|
|
87
105
|
ToolHooks,
|
|
88
106
|
SessionStartHook,
|
|
89
107
|
SessionStartHookContext,
|
|
90
108
|
SessionEndHook,
|
|
91
109
|
SessionEndHookContext,
|
|
110
|
+
// Subagent types
|
|
92
111
|
SubagentConfig,
|
|
93
112
|
SubagentHooks,
|
|
94
113
|
SubagentInput,
|
|
114
|
+
// Task types
|
|
95
115
|
TaskStatus,
|
|
96
116
|
WorkflowTask,
|
|
97
117
|
} from "./lib/types";
|
|
@@ -101,6 +121,9 @@ export {
|
|
|
101
121
|
agentStateChangeUpdateName,
|
|
102
122
|
} from "./lib/types";
|
|
103
123
|
|
|
124
|
+
// Model invoker contract
|
|
125
|
+
export type { ModelInvoker, ModelInvokerConfig } from "./lib/model-invoker";
|
|
126
|
+
|
|
104
127
|
// Subagent support
|
|
105
128
|
export { createSubagentTool } from "./tools/subagent/tool";
|
|
106
129
|
export type { SubagentArgs } from "./tools/subagent/tool";
|
|
@@ -113,10 +136,6 @@ export { createReadSkillTool } from "./tools/read-skill/tool";
|
|
|
113
136
|
export { createReadSkillHandler } from "./tools/read-skill/handler";
|
|
114
137
|
export type { ReadSkillArgs } from "./tools/read-skill/tool";
|
|
115
138
|
|
|
116
|
-
// Activity type interfaces (types only, no runtime code)
|
|
117
|
-
// These are safe to import in workflows for typing proxyActivities
|
|
118
|
-
export type { ZeitlichSharedActivities } from "./activities";
|
|
119
|
-
|
|
120
139
|
// Tool definitions (schemas only - no handlers)
|
|
121
140
|
export { globTool } from "./tools/glob/tool";
|
|
122
141
|
export type { GlobArgs } from "./tools/glob/tool";
|
package/tsup.config.ts
CHANGED
package/src/activities.ts
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import type Redis from "ioredis";
|
|
2
|
-
import { createThreadManager } from "./lib/thread-manager";
|
|
3
|
-
import type { ToolResultConfig } from "./lib/types";
|
|
4
|
-
import {
|
|
5
|
-
type MessageContent,
|
|
6
|
-
type StoredMessage,
|
|
7
|
-
} from "@langchain/core/messages";
|
|
8
|
-
/**
|
|
9
|
-
* Shared Zeitlich activities - thread management and message handling
|
|
10
|
-
* Note: runAgent is workflow-specific and should be created per-workflow
|
|
11
|
-
*/
|
|
12
|
-
export interface ZeitlichSharedActivities {
|
|
13
|
-
/**
|
|
14
|
-
* Append a tool result to the thread.
|
|
15
|
-
* Handles JSON serialization and optional cache points.
|
|
16
|
-
*/
|
|
17
|
-
appendToolResult(config: ToolResultConfig): Promise<void>;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Initialize an empty thread.
|
|
21
|
-
*/
|
|
22
|
-
initializeThread(threadId: string): Promise<void>;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Append messages to a thread.
|
|
26
|
-
*/
|
|
27
|
-
appendThreadMessages(
|
|
28
|
-
threadId: string,
|
|
29
|
-
messages: StoredMessage[]
|
|
30
|
-
): Promise<void>;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Append a human message to a thread.
|
|
34
|
-
*/
|
|
35
|
-
appendHumanMessage(
|
|
36
|
-
threadId: string,
|
|
37
|
-
content: string | MessageContent
|
|
38
|
-
): Promise<void>;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Append a system message to a thread.
|
|
42
|
-
*/
|
|
43
|
-
appendSystemMessage(threadId: string, content: string): Promise<void>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Creates shared Temporal activities for thread management
|
|
48
|
-
*
|
|
49
|
-
* @returns An object containing the shared activity functions
|
|
50
|
-
*
|
|
51
|
-
* @experimental The Zeitlich integration is an experimental feature; APIs may change without notice.
|
|
52
|
-
*/
|
|
53
|
-
export function createSharedActivities(redis: Redis): ZeitlichSharedActivities {
|
|
54
|
-
return {
|
|
55
|
-
async appendToolResult(config: ToolResultConfig): Promise<void> {
|
|
56
|
-
const { threadId, toolCallId, content } = config;
|
|
57
|
-
const thread = createThreadManager({ redis, threadId });
|
|
58
|
-
|
|
59
|
-
await thread.appendToolMessage(content, toolCallId);
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
async initializeThread(threadId: string): Promise<void> {
|
|
63
|
-
const thread = createThreadManager({ redis, threadId });
|
|
64
|
-
await thread.initialize();
|
|
65
|
-
},
|
|
66
|
-
|
|
67
|
-
async appendThreadMessages(
|
|
68
|
-
threadId: string,
|
|
69
|
-
messages: StoredMessage[]
|
|
70
|
-
): Promise<void> {
|
|
71
|
-
const thread = createThreadManager({ redis, threadId });
|
|
72
|
-
await thread.append(messages);
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
async appendHumanMessage(
|
|
76
|
-
threadId: string,
|
|
77
|
-
content: string | MessageContent
|
|
78
|
-
): Promise<void> {
|
|
79
|
-
const thread = createThreadManager({ redis, threadId });
|
|
80
|
-
await thread.appendHumanMessage(content);
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
async appendSystemMessage(
|
|
84
|
-
threadId: string,
|
|
85
|
-
content: string
|
|
86
|
-
): Promise<void> {
|
|
87
|
-
const thread = createThreadManager({ redis, threadId });
|
|
88
|
-
await thread.appendSystemMessage(content);
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
}
|
package/src/plugin.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { SimplePlugin } from "@temporalio/plugin";
|
|
2
|
-
import { createSharedActivities } from "./activities";
|
|
3
|
-
import type Redis from "ioredis";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Options for the Zeitlich plugin
|
|
7
|
-
*
|
|
8
|
-
* @experimental The Zeitlich plugin is an experimental feature; APIs may change without notice.
|
|
9
|
-
*/
|
|
10
|
-
export interface ZeitlichPluginOptions {
|
|
11
|
-
redis: Redis;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* A Temporal plugin that integrates Zeitlich for use in workflows.
|
|
16
|
-
* This plugin creates shared activities for thread management.
|
|
17
|
-
* Workflow-specific activities (like runAgent) should be created separately.
|
|
18
|
-
*
|
|
19
|
-
* @experimental The Zeitlich plugin is an experimental feature; APIs may change without notice.
|
|
20
|
-
*/
|
|
21
|
-
export class ZeitlichPlugin extends SimplePlugin {
|
|
22
|
-
constructor(options: ZeitlichPluginOptions) {
|
|
23
|
-
super({
|
|
24
|
-
name: "ZeitlichPlugin",
|
|
25
|
-
activities: createSharedActivities(options.redis),
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
}
|