zeitlich 0.2.15 → 0.2.17
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 +125 -64
- package/dist/adapters/sandbox/daytona/index.cjs +52 -23
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +10 -2
- package/dist/adapters/sandbox/daytona/index.d.ts +10 -2
- package/dist/adapters/sandbox/daytona/index.js +52 -23
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.cjs +21 -16
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.ts +1 -1
- package/dist/adapters/sandbox/inmemory/index.js +21 -16
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/virtual/index.cjs +83 -38
- package/dist/adapters/sandbox/virtual/index.cjs.map +1 -1
- package/dist/adapters/sandbox/virtual/index.d.cts +6 -6
- package/dist/adapters/sandbox/virtual/index.d.ts +6 -6
- package/dist/adapters/sandbox/virtual/index.js +80 -38
- package/dist/adapters/sandbox/virtual/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +2 -2
- package/dist/adapters/thread/google-genai/index.d.ts +2 -2
- package/dist/adapters/thread/langchain/index.cjs +2 -2
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +2 -2
- package/dist/adapters/thread/langchain/index.d.ts +2 -2
- package/dist/adapters/thread/langchain/index.js +2 -2
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/index.cjs +102 -10
- 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 +98 -11
- package/dist/index.js.map +1 -1
- package/dist/{types-CwwgQ_9H.d.ts → queries-BlC1I3DK.d.ts} +48 -3
- package/dist/{types-BVP87m_W.d.cts → queries-DlJ3jE48.d.cts} +48 -3
- package/dist/{types-CDubRtad.d.cts → types-BMRzfELQ.d.cts} +2 -0
- package/dist/{types-CDubRtad.d.ts → types-BMRzfELQ.d.ts} +2 -0
- package/dist/{types-Dje1TdH6.d.cts → types-Bh-BbfCp.d.cts} +31 -12
- package/dist/{types-BWvIYK28.d.ts → types-NkiAxU4t.d.ts} +31 -12
- package/dist/workflow.cjs +102 -10
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +114 -40
- package/dist/workflow.d.ts +114 -40
- package/dist/workflow.js +98 -11
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/sandbox/daytona/filesystem.ts +43 -19
- package/src/adapters/sandbox/daytona/index.ts +16 -3
- package/src/adapters/sandbox/daytona/types.ts +4 -0
- package/src/adapters/sandbox/inmemory/index.ts +22 -16
- package/src/adapters/sandbox/virtual/filesystem.ts +29 -31
- package/src/adapters/sandbox/virtual/index.ts +7 -3
- package/src/adapters/sandbox/virtual/provider.ts +5 -2
- package/src/adapters/sandbox/virtual/queries.ts +97 -0
- package/src/adapters/sandbox/virtual/types.ts +3 -0
- package/src/adapters/sandbox/virtual/with-virtual-sandbox.ts +4 -3
- package/src/adapters/thread/langchain/activities.ts +7 -5
- package/src/lib/sandbox/tree.integration.test.ts +153 -0
- package/src/lib/sandbox/types.ts +2 -0
- package/src/lib/session/session-edge-cases.integration.test.ts +962 -0
- package/src/lib/session/session.integration.test.ts +853 -0
- package/src/lib/session/session.ts +5 -4
- package/src/lib/skills/skills.integration.test.ts +308 -0
- package/src/lib/state/manager.integration.test.ts +342 -0
- package/src/lib/subagent/define.ts +34 -47
- package/src/lib/subagent/handler.ts +9 -6
- package/src/lib/subagent/index.ts +4 -1
- package/src/lib/subagent/subagent.integration.test.ts +573 -0
- package/src/lib/subagent/types.ts +40 -10
- package/src/lib/subagent/workflow.ts +114 -0
- package/src/lib/thread/id.test.ts +50 -0
- package/src/lib/tool-router/auto-append-sandbox.integration.test.ts +344 -0
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +623 -0
- package/src/lib/tool-router/router.integration.test.ts +699 -0
- package/src/lib/types.test.ts +29 -0
- package/src/lib/workflow.test.ts +131 -0
- package/src/lib/workflow.ts +45 -0
- package/src/workflow.ts +12 -2
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { isTerminalStatus } from "./types";
|
|
3
|
+
import type { AgentStatus } from "./types";
|
|
4
|
+
|
|
5
|
+
describe("isTerminalStatus", () => {
|
|
6
|
+
it("returns true for COMPLETED", () => {
|
|
7
|
+
expect(isTerminalStatus("COMPLETED")).toBe(true);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("returns true for FAILED", () => {
|
|
11
|
+
expect(isTerminalStatus("FAILED")).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("returns true for CANCELLED", () => {
|
|
15
|
+
expect(isTerminalStatus("CANCELLED")).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("returns false for RUNNING", () => {
|
|
19
|
+
expect(isTerminalStatus("RUNNING")).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("returns false for WAITING_FOR_INPUT", () => {
|
|
23
|
+
expect(isTerminalStatus("WAITING_FOR_INPUT")).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("returns false for unknown status", () => {
|
|
27
|
+
expect(isTerminalStatus("UNKNOWN" as AgentStatus)).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
defineWorkflow,
|
|
4
|
+
type WorkflowInput,
|
|
5
|
+
type WorkflowSessionInput,
|
|
6
|
+
} from "./workflow";
|
|
7
|
+
|
|
8
|
+
describe("defineWorkflow", () => {
|
|
9
|
+
it("maps previousThreadId to threadId + continueThread", async () => {
|
|
10
|
+
let capturedSession: WorkflowSessionInput | undefined;
|
|
11
|
+
|
|
12
|
+
const workflow = defineWorkflow(async (_input, sessionInput) => {
|
|
13
|
+
capturedSession = sessionInput;
|
|
14
|
+
return { ok: true };
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
await workflow({}, { previousThreadId: "prev-42" });
|
|
18
|
+
|
|
19
|
+
expect(capturedSession).toEqual({
|
|
20
|
+
threadId: "prev-42",
|
|
21
|
+
continueThread: true,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("maps sandboxId", async () => {
|
|
26
|
+
let capturedSession: WorkflowSessionInput | undefined;
|
|
27
|
+
|
|
28
|
+
const workflow = defineWorkflow(async (_input, sessionInput) => {
|
|
29
|
+
capturedSession = sessionInput;
|
|
30
|
+
return { ok: true };
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await workflow({}, { sandboxId: "sb-123" });
|
|
34
|
+
|
|
35
|
+
expect(capturedSession).toEqual({ sandboxId: "sb-123" });
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("maps both previousThreadId and sandboxId together", async () => {
|
|
39
|
+
let capturedSession: WorkflowSessionInput | undefined;
|
|
40
|
+
|
|
41
|
+
const workflow = defineWorkflow(async (_input, sessionInput) => {
|
|
42
|
+
capturedSession = sessionInput;
|
|
43
|
+
return { ok: true };
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await workflow({}, { previousThreadId: "prev-1", sandboxId: "sb-1" });
|
|
47
|
+
|
|
48
|
+
expect(capturedSession).toEqual({
|
|
49
|
+
threadId: "prev-1",
|
|
50
|
+
continueThread: true,
|
|
51
|
+
sandboxId: "sb-1",
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("returns empty sessionInput when no previousThreadId or sandboxId", async () => {
|
|
56
|
+
let capturedSession: WorkflowSessionInput | undefined;
|
|
57
|
+
|
|
58
|
+
const workflow = defineWorkflow(async (_input, sessionInput) => {
|
|
59
|
+
capturedSession = sessionInput;
|
|
60
|
+
return { ok: true };
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
await workflow({});
|
|
64
|
+
|
|
65
|
+
expect(capturedSession).toEqual({});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("passes full input as first argument", async () => {
|
|
69
|
+
let capturedInput: unknown;
|
|
70
|
+
|
|
71
|
+
const workflow = defineWorkflow<{
|
|
72
|
+
prompt: string;
|
|
73
|
+
metadata: { key: string };
|
|
74
|
+
previousThreadId?: string;
|
|
75
|
+
sandboxId?: string;
|
|
76
|
+
}, { ok: boolean }>(async (input, _sessionInput) => {
|
|
77
|
+
capturedInput = input;
|
|
78
|
+
return { ok: true };
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
await workflow({
|
|
82
|
+
prompt: "research",
|
|
83
|
+
metadata: { key: "val" },
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
expect(capturedInput).toEqual({
|
|
87
|
+
prompt: "research",
|
|
88
|
+
metadata: { key: "val" },
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("passes workflowInput as second argument only", async () => {
|
|
93
|
+
let capturedInput: unknown;
|
|
94
|
+
let capturedSession: WorkflowSessionInput | undefined;
|
|
95
|
+
|
|
96
|
+
const workflow = defineWorkflow<{ prompt: string }, { ok: boolean }>(
|
|
97
|
+
async (input, sessionInput) => {
|
|
98
|
+
capturedInput = input;
|
|
99
|
+
capturedSession = sessionInput;
|
|
100
|
+
return { ok: true };
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const workflowInput: WorkflowInput = {
|
|
105
|
+
previousThreadId: "prev",
|
|
106
|
+
sandboxId: "sb",
|
|
107
|
+
};
|
|
108
|
+
await workflow({ prompt: "go" }, workflowInput);
|
|
109
|
+
|
|
110
|
+
expect(capturedInput).toEqual({ prompt: "go" });
|
|
111
|
+
expect(capturedSession).toEqual({
|
|
112
|
+
threadId: "prev",
|
|
113
|
+
continueThread: true,
|
|
114
|
+
sandboxId: "sb",
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("returns the handler response unchanged", async () => {
|
|
119
|
+
const workflow = defineWorkflow(async () => ({
|
|
120
|
+
finalMessage: "result text",
|
|
121
|
+
threadId: "thread-123",
|
|
122
|
+
}));
|
|
123
|
+
|
|
124
|
+
const result = await workflow({});
|
|
125
|
+
|
|
126
|
+
expect(result).toEqual({
|
|
127
|
+
finalMessage: "result text",
|
|
128
|
+
threadId: "thread-123",
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session config fields derived from a main workflow input, ready to spread
|
|
3
|
+
* into `createSession`.
|
|
4
|
+
*/
|
|
5
|
+
export interface WorkflowSessionInput {
|
|
6
|
+
/** Thread ID to continue (set from `input.previousThreadId`) */
|
|
7
|
+
threadId?: string;
|
|
8
|
+
/** Whether to continue an existing thread (true when `previousThreadId` is present) */
|
|
9
|
+
continueThread?: boolean;
|
|
10
|
+
/** Optional sandbox ID forwarded to the session */
|
|
11
|
+
sandboxId?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Raw workflow input fields that map into `WorkflowSessionInput`. */
|
|
15
|
+
export interface WorkflowInput {
|
|
16
|
+
/** When set, continue this thread instead of starting fresh */
|
|
17
|
+
previousThreadId?: string;
|
|
18
|
+
/** Optional sandbox ID to reuse */
|
|
19
|
+
sandboxId?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Wraps a main workflow function, translating workflow input fields into
|
|
24
|
+
* session-compatible fields that can be spread directly into `createSession`.
|
|
25
|
+
*
|
|
26
|
+
* The wrapper:
|
|
27
|
+
* - Accepts a generic typed `input` as first argument
|
|
28
|
+
* - Accepts optional `workflowInput` ({ previousThreadId, sandboxId }) as second argument
|
|
29
|
+
* - Derives `threadId` + `continueThread` from `workflowInput.previousThreadId`
|
|
30
|
+
* - Derives `sandboxId` from `workflowInput.sandboxId`
|
|
31
|
+
*/
|
|
32
|
+
export function defineWorkflow<TInput, TResult>(
|
|
33
|
+
fn: (input: TInput, sessionInput: WorkflowSessionInput) => Promise<TResult>,
|
|
34
|
+
): (input: TInput, workflowInput?: WorkflowInput) => Promise<TResult> {
|
|
35
|
+
return async (input, workflowInput = {}) => {
|
|
36
|
+
const sessionInput: WorkflowSessionInput = {
|
|
37
|
+
...(workflowInput.previousThreadId && {
|
|
38
|
+
threadId: workflowInput.previousThreadId,
|
|
39
|
+
continueThread: true,
|
|
40
|
+
}),
|
|
41
|
+
...(workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }),
|
|
42
|
+
};
|
|
43
|
+
return fn(input, sessionInput);
|
|
44
|
+
};
|
|
45
|
+
}
|
package/src/workflow.ts
CHANGED
|
@@ -25,6 +25,8 @@ export {
|
|
|
25
25
|
proxySandboxOps,
|
|
26
26
|
} from "./lib/session";
|
|
27
27
|
export type { ZeitlichSession, ThreadOps, SessionConfig } from "./lib/session";
|
|
28
|
+
export { defineWorkflow } from "./lib/workflow";
|
|
29
|
+
export type { WorkflowInput, WorkflowSessionInput } from "./lib/workflow";
|
|
28
30
|
|
|
29
31
|
// Thread utilities
|
|
30
32
|
export { getShortId } from "./lib/thread";
|
|
@@ -45,7 +47,7 @@ export {
|
|
|
45
47
|
hasNoOtherToolCalls,
|
|
46
48
|
defineTool,
|
|
47
49
|
} from "./lib/tool-router";
|
|
48
|
-
export { defineSubagent } from "./lib/subagent";
|
|
50
|
+
export { defineSubagent, defineSubagentWorkflow } from "./lib/subagent";
|
|
49
51
|
export type {
|
|
50
52
|
// Tool definition types
|
|
51
53
|
ToolDefinition,
|
|
@@ -130,10 +132,12 @@ export type {
|
|
|
130
132
|
// Subagent types
|
|
131
133
|
export type {
|
|
132
134
|
SubagentConfig,
|
|
135
|
+
SubagentDefinition,
|
|
133
136
|
SubagentHooks,
|
|
134
|
-
SubagentInput,
|
|
135
137
|
SubagentHandlerResponse,
|
|
136
138
|
SubagentWorkflow,
|
|
139
|
+
SubagentWorkflowInput,
|
|
140
|
+
SubagentSessionInput,
|
|
137
141
|
} from "./lib/subagent/types";
|
|
138
142
|
// Sandbox types (workflow-safe — no activity-side code)
|
|
139
143
|
export type {
|
|
@@ -159,6 +163,12 @@ export {
|
|
|
159
163
|
// pulling activity-side code like VirtualSandboxFileSystem / Provider).
|
|
160
164
|
export { applyVirtualTreeMutations } from "./adapters/sandbox/virtual/mutations";
|
|
161
165
|
export { formatVirtualFileTree } from "./adapters/sandbox/virtual/tree";
|
|
166
|
+
export {
|
|
167
|
+
hasFileWithMimeType,
|
|
168
|
+
filesWithMimeType,
|
|
169
|
+
hasDirectory,
|
|
170
|
+
} from "./adapters/sandbox/virtual/queries";
|
|
171
|
+
|
|
162
172
|
export type {
|
|
163
173
|
FileEntry,
|
|
164
174
|
FileEntryMetadata,
|