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.
Files changed (46) hide show
  1. package/README.md +313 -126
  2. package/dist/adapters/langchain/index.cjs +270 -0
  3. package/dist/adapters/langchain/index.cjs.map +1 -0
  4. package/dist/adapters/langchain/index.d.cts +132 -0
  5. package/dist/adapters/langchain/index.d.ts +132 -0
  6. package/dist/adapters/langchain/index.js +265 -0
  7. package/dist/adapters/langchain/index.js.map +1 -0
  8. package/dist/index.cjs +89 -209
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +62 -46
  11. package/dist/index.d.ts +62 -46
  12. package/dist/index.js +88 -208
  13. package/dist/index.js.map +1 -1
  14. package/dist/{workflow-BhjsEQc1.d.cts → model-invoker-y_zlyMqu.d.cts} +45 -482
  15. package/dist/{workflow-BhjsEQc1.d.ts → model-invoker-y_zlyMqu.d.ts} +45 -482
  16. package/dist/thread-manager-qc0g5Rvd.d.cts +39 -0
  17. package/dist/thread-manager-qc0g5Rvd.d.ts +39 -0
  18. package/dist/workflow.cjs +59 -27
  19. package/dist/workflow.cjs.map +1 -1
  20. package/dist/workflow.d.cts +459 -6
  21. package/dist/workflow.d.ts +459 -6
  22. package/dist/workflow.js +60 -29
  23. package/dist/workflow.js.map +1 -1
  24. package/package.json +17 -2
  25. package/src/adapters/langchain/activities.ts +120 -0
  26. package/src/adapters/langchain/index.ts +38 -0
  27. package/src/adapters/langchain/model-invoker.ts +102 -0
  28. package/src/adapters/langchain/thread-manager.ts +142 -0
  29. package/src/index.ts +24 -23
  30. package/src/lib/fs.ts +25 -0
  31. package/src/lib/model-invoker.ts +15 -75
  32. package/src/lib/session.ts +52 -21
  33. package/src/lib/state-manager.ts +23 -5
  34. package/src/lib/thread-id.ts +25 -0
  35. package/src/lib/thread-manager.ts +18 -142
  36. package/src/lib/tool-router.ts +12 -18
  37. package/src/lib/types.ts +26 -10
  38. package/src/lib/workflow-helpers.ts +50 -0
  39. package/src/tools/ask-user-question/handler.ts +25 -1
  40. package/src/tools/bash/handler.ts +13 -0
  41. package/src/tools/subagent/handler.ts +16 -5
  42. package/src/tools/subagent/tool.ts +34 -15
  43. package/src/workflow.ts +26 -7
  44. package/tsup.config.ts +1 -0
  45. package/src/activities.ts +0 -91
  46. 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) => `## ${s.agentName}
14
- ${s.description}`).join("\n\n");
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: z14__default.default.object({
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}-${workflow.uuid4()}`;
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
- await initializeThread(threadId);
514
- if (appendSystemPrompt) {
515
- if (!systemPrompt || systemPrompt.trim() === "") {
516
- throw workflow.ApplicationFailure.create({
517
- message: "No system prompt in state",
518
- nonRetryable: true
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
- const activities = workflow.proxyActivities(
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;