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
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import Redis from 'ioredis';
|
|
2
|
+
|
|
3
|
+
interface ThreadManagerConfig<T> {
|
|
4
|
+
redis: Redis;
|
|
5
|
+
threadId: string;
|
|
6
|
+
/** Thread key, defaults to 'messages' */
|
|
7
|
+
key?: string;
|
|
8
|
+
/** Custom serializer, defaults to JSON.stringify */
|
|
9
|
+
serialize?: (message: T) => string;
|
|
10
|
+
/** Custom deserializer, defaults to JSON.parse */
|
|
11
|
+
deserialize?: (raw: string) => T;
|
|
12
|
+
/**
|
|
13
|
+
* Extract a unique id from a message for idempotent appends.
|
|
14
|
+
* When provided, `append` uses an atomic Lua script to skip duplicate writes.
|
|
15
|
+
*/
|
|
16
|
+
idOf?: (message: T) => string;
|
|
17
|
+
}
|
|
18
|
+
/** Generic thread manager for any message type */
|
|
19
|
+
interface BaseThreadManager<T> {
|
|
20
|
+
/** Initialize an empty thread */
|
|
21
|
+
initialize(): Promise<void>;
|
|
22
|
+
/** Load all messages from the thread */
|
|
23
|
+
load(): Promise<T[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Append messages to the thread.
|
|
26
|
+
* When `idOf` is configured, appends are idempotent — retries with the
|
|
27
|
+
* same message ids are atomically skipped via a Redis Lua script.
|
|
28
|
+
*/
|
|
29
|
+
append(messages: T[]): Promise<void>;
|
|
30
|
+
/** Delete the thread */
|
|
31
|
+
delete(): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Creates a generic thread manager for handling conversation state in Redis.
|
|
35
|
+
* Framework-agnostic — works with any serializable message type.
|
|
36
|
+
*/
|
|
37
|
+
declare function createThreadManager<T>(config: ThreadManagerConfig<T>): BaseThreadManager<T>;
|
|
38
|
+
|
|
39
|
+
export { type BaseThreadManager as B, type ThreadManagerConfig as T, createThreadManager as c };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import Redis from 'ioredis';
|
|
2
|
+
|
|
3
|
+
interface ThreadManagerConfig<T> {
|
|
4
|
+
redis: Redis;
|
|
5
|
+
threadId: string;
|
|
6
|
+
/** Thread key, defaults to 'messages' */
|
|
7
|
+
key?: string;
|
|
8
|
+
/** Custom serializer, defaults to JSON.stringify */
|
|
9
|
+
serialize?: (message: T) => string;
|
|
10
|
+
/** Custom deserializer, defaults to JSON.parse */
|
|
11
|
+
deserialize?: (raw: string) => T;
|
|
12
|
+
/**
|
|
13
|
+
* Extract a unique id from a message for idempotent appends.
|
|
14
|
+
* When provided, `append` uses an atomic Lua script to skip duplicate writes.
|
|
15
|
+
*/
|
|
16
|
+
idOf?: (message: T) => string;
|
|
17
|
+
}
|
|
18
|
+
/** Generic thread manager for any message type */
|
|
19
|
+
interface BaseThreadManager<T> {
|
|
20
|
+
/** Initialize an empty thread */
|
|
21
|
+
initialize(): Promise<void>;
|
|
22
|
+
/** Load all messages from the thread */
|
|
23
|
+
load(): Promise<T[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Append messages to the thread.
|
|
26
|
+
* When `idOf` is configured, appends are idempotent — retries with the
|
|
27
|
+
* same message ids are atomically skipped via a Redis Lua script.
|
|
28
|
+
*/
|
|
29
|
+
append(messages: T[]): Promise<void>;
|
|
30
|
+
/** Delete the thread */
|
|
31
|
+
delete(): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Creates a generic thread manager for handling conversation state in Redis.
|
|
35
|
+
* Framework-agnostic — works with any serializable message type.
|
|
36
|
+
*/
|
|
37
|
+
declare function createThreadManager<T>(config: ThreadManagerConfig<T>): BaseThreadManager<T>;
|
|
38
|
+
|
|
39
|
+
export { type BaseThreadManager as B, type ThreadManagerConfig as T, createThreadManager as c };
|
package/dist/workflow.cjs
CHANGED
|
@@ -10,8 +10,11 @@ var z14__default = /*#__PURE__*/_interopDefault(z14);
|
|
|
10
10
|
// src/lib/session.ts
|
|
11
11
|
var SUBAGENT_TOOL_NAME = "Subagent";
|
|
12
12
|
function buildSubagentDescription(subagents) {
|
|
13
|
-
const subagentList = subagents.map((s) =>
|
|
14
|
-
|
|
13
|
+
const subagentList = subagents.map((s) => {
|
|
14
|
+
const continuation = s.allowThreadContinuation ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
|
|
15
|
+
return `## ${s.agentName}
|
|
16
|
+
${s.description}${continuation}`;
|
|
17
|
+
}).join("\n\n");
|
|
15
18
|
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.
|
|
16
19
|
|
|
17
20
|
# Available subagents:
|
|
@@ -23,16 +26,38 @@ function createSubagentTool(subagents) {
|
|
|
23
26
|
throw new Error("createTaskTool requires at least one subagent");
|
|
24
27
|
}
|
|
25
28
|
const names = subagents.map((s) => s.agentName);
|
|
29
|
+
const hasThreadContinuation = subagents.some(
|
|
30
|
+
(s) => s.allowThreadContinuation
|
|
31
|
+
);
|
|
32
|
+
const baseFields = {
|
|
33
|
+
subagent: z14__default.default.enum(names).describe("The type of subagent to launch"),
|
|
34
|
+
description: z14__default.default.string().describe("A short (3-5 word) description of the task"),
|
|
35
|
+
prompt: z14__default.default.string().describe("The task for the agent to perform")
|
|
36
|
+
};
|
|
37
|
+
const schema = hasThreadContinuation ? z14__default.default.object({
|
|
38
|
+
...baseFields,
|
|
39
|
+
threadId: z14__default.default.string().nullable().describe(
|
|
40
|
+
"Thread ID to continue an existing conversation, or null to start a new one"
|
|
41
|
+
)
|
|
42
|
+
}) : z14__default.default.object(baseFields);
|
|
26
43
|
return {
|
|
27
44
|
name: SUBAGENT_TOOL_NAME,
|
|
28
45
|
description: buildSubagentDescription(subagents),
|
|
29
|
-
schema
|
|
30
|
-
subagent: z14__default.default.enum(names).describe("The type of subagent to launch"),
|
|
31
|
-
description: z14__default.default.string().describe("A short (3-5 word) description of the task"),
|
|
32
|
-
prompt: z14__default.default.string().describe("The task for the agent to perform")
|
|
33
|
-
})
|
|
46
|
+
schema
|
|
34
47
|
};
|
|
35
48
|
}
|
|
49
|
+
var BASE62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
50
|
+
function getShortId(length = 12) {
|
|
51
|
+
const hex = workflow.uuid4().replace(/-/g, "");
|
|
52
|
+
let result = "";
|
|
53
|
+
for (let i = 0; i < length; i++) {
|
|
54
|
+
const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
55
|
+
result += BASE62[byte % BASE62.length];
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/tools/subagent/handler.ts
|
|
36
61
|
function createSubagentHandler(subagents) {
|
|
37
62
|
const { taskQueue: parentTaskQueue } = workflow.workflowInfo();
|
|
38
63
|
return async (args) => {
|
|
@@ -42,17 +67,18 @@ function createSubagentHandler(subagents) {
|
|
|
42
67
|
`Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.agentName).join(", ")}`
|
|
43
68
|
);
|
|
44
69
|
}
|
|
45
|
-
const childWorkflowId = `${args.subagent}-${
|
|
70
|
+
const childWorkflowId = `${args.subagent}-${getShortId()}`;
|
|
46
71
|
const input = {
|
|
47
72
|
prompt: args.prompt,
|
|
48
|
-
...config.context && { context: config.context }
|
|
73
|
+
...config.context && { context: config.context },
|
|
74
|
+
...args.threadId && config.allowThreadContinuation && { threadId: args.threadId }
|
|
49
75
|
};
|
|
50
76
|
const childOpts = {
|
|
51
77
|
workflowId: childWorkflowId,
|
|
52
78
|
args: [input],
|
|
53
79
|
taskQueue: config.taskQueue ?? parentTaskQueue
|
|
54
80
|
};
|
|
55
|
-
const { toolResponse, data, usage } = typeof config.workflow === "string" ? await workflow.executeChild(config.workflow, childOpts) : await workflow.executeChild(config.workflow, childOpts);
|
|
81
|
+
const { toolResponse, data, usage, threadId: childThreadId } = typeof config.workflow === "string" ? await workflow.executeChild(config.workflow, childOpts) : await workflow.executeChild(config.workflow, childOpts);
|
|
56
82
|
if (!toolResponse) {
|
|
57
83
|
return {
|
|
58
84
|
toolResponse: "Subagent workflow returned no response",
|
|
@@ -68,8 +94,14 @@ function createSubagentHandler(subagents) {
|
|
|
68
94
|
...usage && { usage }
|
|
69
95
|
};
|
|
70
96
|
}
|
|
97
|
+
let finalToolResponse = toolResponse;
|
|
98
|
+
if (config.allowThreadContinuation && childThreadId) {
|
|
99
|
+
finalToolResponse = typeof toolResponse === "string" ? `${toolResponse}
|
|
100
|
+
|
|
101
|
+
[Thread ID: ${childThreadId}]` : toolResponse;
|
|
102
|
+
}
|
|
71
103
|
return {
|
|
72
|
-
toolResponse,
|
|
104
|
+
toolResponse: finalToolResponse,
|
|
73
105
|
data: validated ? validated.data : data,
|
|
74
106
|
...usage && { usage }
|
|
75
107
|
};
|
|
@@ -438,7 +470,7 @@ function hasNoOtherToolCalls(toolCalls, excludeName) {
|
|
|
438
470
|
|
|
439
471
|
// src/lib/session.ts
|
|
440
472
|
var createSession = async ({
|
|
441
|
-
threadId,
|
|
473
|
+
threadId: providedThreadId,
|
|
442
474
|
agentName,
|
|
443
475
|
maxTurns = 50,
|
|
444
476
|
metadata = {},
|
|
@@ -451,8 +483,10 @@ var createSession = async ({
|
|
|
451
483
|
processToolsInParallel = true,
|
|
452
484
|
hooks = {},
|
|
453
485
|
appendSystemPrompt = true,
|
|
486
|
+
continueThread = false,
|
|
454
487
|
waitForInputTimeout = "48h"
|
|
455
488
|
}) => {
|
|
489
|
+
const threadId = providedThreadId ?? getShortId();
|
|
456
490
|
const {
|
|
457
491
|
appendToolResult,
|
|
458
492
|
appendHumanMessage,
|
|
@@ -510,15 +544,18 @@ var createSession = async ({
|
|
|
510
544
|
});
|
|
511
545
|
}
|
|
512
546
|
const systemPrompt = stateManager.getSystemPrompt();
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
547
|
+
if (!continueThread) {
|
|
548
|
+
if (appendSystemPrompt) {
|
|
549
|
+
if (!systemPrompt || systemPrompt.trim() === "") {
|
|
550
|
+
throw workflow.ApplicationFailure.create({
|
|
551
|
+
message: "No system prompt in state",
|
|
552
|
+
nonRetryable: true
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
await appendSystemMessage(threadId, systemPrompt);
|
|
556
|
+
} else {
|
|
557
|
+
await initializeThread(threadId);
|
|
520
558
|
}
|
|
521
|
-
await appendSystemMessage(threadId, systemPrompt);
|
|
522
559
|
}
|
|
523
560
|
await appendHumanMessage(threadId, await buildContextMessage());
|
|
524
561
|
let exitReason = "completed";
|
|
@@ -600,7 +637,7 @@ var createSession = async ({
|
|
|
600
637
|
};
|
|
601
638
|
};
|
|
602
639
|
function proxyDefaultThreadOps(options) {
|
|
603
|
-
|
|
640
|
+
return workflow.proxyActivities(
|
|
604
641
|
options ?? {
|
|
605
642
|
startToCloseTimeout: "10s",
|
|
606
643
|
retry: {
|
|
@@ -611,12 +648,6 @@ function proxyDefaultThreadOps(options) {
|
|
|
611
648
|
}
|
|
612
649
|
}
|
|
613
650
|
);
|
|
614
|
-
return {
|
|
615
|
-
initializeThread: activities.initializeThread,
|
|
616
|
-
appendHumanMessage: activities.appendHumanMessage,
|
|
617
|
-
appendToolResult: activities.appendToolResult,
|
|
618
|
-
appendSystemMessage: activities.appendSystemMessage
|
|
619
|
-
};
|
|
620
651
|
}
|
|
621
652
|
|
|
622
653
|
// src/lib/types.ts
|
|
@@ -1222,6 +1253,7 @@ exports.createToolRouter = createToolRouter;
|
|
|
1222
1253
|
exports.defineSubagent = defineSubagent;
|
|
1223
1254
|
exports.defineTool = defineTool;
|
|
1224
1255
|
exports.editTool = editTool;
|
|
1256
|
+
exports.getShortId = getShortId;
|
|
1225
1257
|
exports.globTool = globTool;
|
|
1226
1258
|
exports.grepTool = grepTool;
|
|
1227
1259
|
exports.hasNoOtherToolCalls = hasNoOtherToolCalls;
|