zeitlich 0.2.18 → 0.2.20
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/adapters/sandbox/daytona/index.cjs +25 -10
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +4 -1
- package/dist/adapters/sandbox/daytona/index.d.ts +4 -1
- package/dist/adapters/sandbox/daytona/index.js +25 -10
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/virtual/index.d.cts +4 -3
- package/dist/adapters/sandbox/virtual/index.d.ts +4 -3
- package/dist/adapters/thread/google-genai/index.cjs +0 -2
- package/dist/adapters/thread/google-genai/index.cjs.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/google-genai/index.js +0 -2
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/langchain/index.cjs +3 -1
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +3 -3
- package/dist/adapters/thread/langchain/index.d.ts +3 -3
- package/dist/adapters/thread/langchain/index.js +3 -1
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/index.cjs +153 -123
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.js +153 -123
- package/dist/index.js.map +1 -1
- package/dist/{queries-TwukRZ8b.d.ts → queries-KHj5Otv7.d.ts} +1 -1
- package/dist/{queries-DnX72m_Y.d.cts → queries-nIdzTCDS.d.cts} +1 -1
- package/dist/{types-CdB2D5Sq.d.ts → types-By80IE1x.d.ts} +3 -3
- package/dist/{types-CmOSypVk.d.ts → types-Ct2igz9y.d.cts} +6 -4
- package/dist/{types-CmOSypVk.d.cts → types-Ct2igz9y.d.ts} +6 -4
- package/dist/{types-DRvq2miV.d.cts → types-DZ7BkA3-.d.cts} +3 -3
- package/dist/workflow.cjs +70 -40
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +16 -12
- package/dist/workflow.d.ts +16 -12
- package/dist/workflow.js +70 -40
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/sandbox/daytona/filesystem.ts +21 -12
- package/src/adapters/sandbox/daytona/index.ts +24 -23
- package/src/adapters/thread/langchain/thread-manager.ts +11 -7
- package/src/lib/session/session-edge-cases.integration.test.ts +20 -2
- package/src/lib/session/session.integration.test.ts +16 -2
- package/src/lib/session/session.ts +2 -1
- package/src/lib/session/types.ts +2 -1
- package/src/lib/subagent/handler.ts +1 -1
- package/src/lib/subagent/register.ts +3 -9
- package/src/lib/subagent/subagent.integration.test.ts +10 -9
- package/src/lib/subagent/tool.ts +1 -1
- package/src/lib/thread/index.ts +0 -1
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +8 -3
- package/src/lib/tool-router/router.integration.test.ts +8 -3
- package/src/lib/tool-router/router.ts +61 -31
- package/src/lib/tool-router/types.ts +14 -9
- package/src/lib/workflow.test.ts +18 -6
- package/src/lib/workflow.ts +13 -3
- package/src/tools/task-create/handler.ts +3 -6
- package/src/workflow.ts +2 -2
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@ export class DaytonaSandboxFileSystem implements SandboxFileSystem {
|
|
|
19
19
|
|
|
20
20
|
constructor(
|
|
21
21
|
private sandbox: DaytonaSdkSandbox,
|
|
22
|
-
workspaceBase = "/home/daytona"
|
|
22
|
+
workspaceBase = "/home/daytona"
|
|
23
23
|
) {
|
|
24
24
|
this.workspaceBase = posix.resolve("/", workspaceBase);
|
|
25
25
|
}
|
|
@@ -49,10 +49,18 @@ export class DaytonaSandboxFileSystem implements SandboxFileSystem {
|
|
|
49
49
|
await this.sandbox.fs.uploadFile(buf, norm);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
async
|
|
53
|
-
path: string
|
|
54
|
-
content: string | Uint8Array,
|
|
52
|
+
async writeFiles(
|
|
53
|
+
files: { path: string; content: string | Uint8Array }[]
|
|
55
54
|
): Promise<void> {
|
|
55
|
+
await this.sandbox.fs.uploadFiles(
|
|
56
|
+
files.map((f) => ({
|
|
57
|
+
source: Buffer.from(f.content),
|
|
58
|
+
destination: f.path,
|
|
59
|
+
}))
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async appendFile(path: string, content: string | Uint8Array): Promise<void> {
|
|
56
64
|
const norm = this.normalisePath(path);
|
|
57
65
|
let existing: Buffer;
|
|
58
66
|
try {
|
|
@@ -89,10 +97,7 @@ export class DaytonaSandboxFileSystem implements SandboxFileSystem {
|
|
|
89
97
|
};
|
|
90
98
|
}
|
|
91
99
|
|
|
92
|
-
async mkdir(
|
|
93
|
-
path: string,
|
|
94
|
-
_options?: { recursive?: boolean },
|
|
95
|
-
): Promise<void> {
|
|
100
|
+
async mkdir(path: string, _options?: { recursive?: boolean }): Promise<void> {
|
|
96
101
|
const norm = this.normalisePath(path);
|
|
97
102
|
await this.sandbox.fs.createFolder(norm, "755");
|
|
98
103
|
}
|
|
@@ -116,7 +121,7 @@ export class DaytonaSandboxFileSystem implements SandboxFileSystem {
|
|
|
116
121
|
|
|
117
122
|
async rm(
|
|
118
123
|
path: string,
|
|
119
|
-
options?: { recursive?: boolean; force?: boolean }
|
|
124
|
+
options?: { recursive?: boolean; force?: boolean }
|
|
120
125
|
): Promise<void> {
|
|
121
126
|
const norm = this.normalisePath(path);
|
|
122
127
|
try {
|
|
@@ -129,7 +134,7 @@ export class DaytonaSandboxFileSystem implements SandboxFileSystem {
|
|
|
129
134
|
async cp(
|
|
130
135
|
src: string,
|
|
131
136
|
dest: string,
|
|
132
|
-
options?: { recursive?: boolean }
|
|
137
|
+
options?: { recursive?: boolean }
|
|
133
138
|
): Promise<void> {
|
|
134
139
|
const normSrc = this.normalisePath(src);
|
|
135
140
|
const normDest = this.normalisePath(dest);
|
|
@@ -138,9 +143,13 @@ export class DaytonaSandboxFileSystem implements SandboxFileSystem {
|
|
|
138
143
|
if (!options?.recursive) {
|
|
139
144
|
throw new Error(`EISDIR: is a directory (use recursive): ${src}`);
|
|
140
145
|
}
|
|
141
|
-
await this.sandbox.process.executeCommand(
|
|
146
|
+
await this.sandbox.process.executeCommand(
|
|
147
|
+
`cp -r "${normSrc}" "${normDest}"`
|
|
148
|
+
);
|
|
142
149
|
} else {
|
|
143
|
-
await this.sandbox.process.executeCommand(
|
|
150
|
+
await this.sandbox.process.executeCommand(
|
|
151
|
+
`cp "${normSrc}" "${normDest}"`
|
|
152
|
+
);
|
|
144
153
|
}
|
|
145
154
|
}
|
|
146
155
|
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Daytona,
|
|
3
|
-
type Sandbox as DaytonaSdkSandbox,
|
|
4
|
-
} from "@daytonaio/sdk";
|
|
1
|
+
import { Daytona, type Sandbox as DaytonaSdkSandbox } from "@daytonaio/sdk";
|
|
5
2
|
import type {
|
|
6
3
|
Sandbox,
|
|
7
4
|
SandboxCapabilities,
|
|
@@ -38,7 +35,7 @@ class DaytonaSandboxImpl implements Sandbox {
|
|
|
38
35
|
constructor(
|
|
39
36
|
readonly id: string,
|
|
40
37
|
private sdkSandbox: DaytonaSdkSandbox,
|
|
41
|
-
workspaceBase = "/home/daytona"
|
|
38
|
+
workspaceBase = "/home/daytona"
|
|
42
39
|
) {
|
|
43
40
|
this.fs = new DaytonaSandboxFileSystem(sdkSandbox, workspaceBase);
|
|
44
41
|
}
|
|
@@ -48,7 +45,7 @@ class DaytonaSandboxImpl implements Sandbox {
|
|
|
48
45
|
command,
|
|
49
46
|
options?.cwd,
|
|
50
47
|
options?.env,
|
|
51
|
-
options?.timeout
|
|
48
|
+
options?.timeout
|
|
52
49
|
);
|
|
53
50
|
|
|
54
51
|
return {
|
|
@@ -67,9 +64,10 @@ class DaytonaSandboxImpl implements Sandbox {
|
|
|
67
64
|
// DaytonaSandboxProvider
|
|
68
65
|
// ============================================================================
|
|
69
66
|
|
|
70
|
-
export class DaytonaSandboxProvider
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
export class DaytonaSandboxProvider implements SandboxProvider<
|
|
68
|
+
DaytonaSandboxCreateOptions,
|
|
69
|
+
DaytonaSandbox
|
|
70
|
+
> {
|
|
73
71
|
readonly id = "daytona";
|
|
74
72
|
readonly capabilities: SandboxCapabilities = {
|
|
75
73
|
filesystem: true,
|
|
@@ -79,7 +77,6 @@ export class DaytonaSandboxProvider
|
|
|
79
77
|
|
|
80
78
|
private client: Daytona;
|
|
81
79
|
private readonly defaultWorkspaceBase: string;
|
|
82
|
-
private workspaceBaseById = new Map<string, string>();
|
|
83
80
|
|
|
84
81
|
constructor(config?: DaytonaSandboxConfig) {
|
|
85
82
|
this.client = new Daytona(config);
|
|
@@ -87,7 +84,7 @@ export class DaytonaSandboxProvider
|
|
|
87
84
|
}
|
|
88
85
|
|
|
89
86
|
async create(
|
|
90
|
-
options?: DaytonaSandboxCreateOptions
|
|
87
|
+
options?: DaytonaSandboxCreateOptions
|
|
91
88
|
): Promise<SandboxCreateResult> {
|
|
92
89
|
const sdkSandbox = await this.client.create(
|
|
93
90
|
{
|
|
@@ -99,21 +96,24 @@ export class DaytonaSandboxProvider
|
|
|
99
96
|
autoArchiveInterval: options?.autoArchiveInterval,
|
|
100
97
|
autoDeleteInterval: options?.autoDeleteInterval,
|
|
101
98
|
},
|
|
102
|
-
{ timeout: options?.timeout ?? 60 }
|
|
99
|
+
{ timeout: options?.timeout ?? 60 }
|
|
103
100
|
);
|
|
104
101
|
|
|
105
102
|
const workspaceBase = options?.workspaceBase ?? this.defaultWorkspaceBase;
|
|
106
|
-
|
|
103
|
+
|
|
107
104
|
const sandbox = new DaytonaSandboxImpl(
|
|
108
105
|
sdkSandbox.id,
|
|
109
106
|
sdkSandbox,
|
|
110
|
-
workspaceBase
|
|
107
|
+
workspaceBase
|
|
111
108
|
);
|
|
112
109
|
|
|
113
110
|
if (options?.initialFiles) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
await sandbox.fs.writeFiles(
|
|
112
|
+
Object.entries(options.initialFiles).map(([path, content]) => ({
|
|
113
|
+
path,
|
|
114
|
+
content,
|
|
115
|
+
}))
|
|
116
|
+
);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
return { sandbox };
|
|
@@ -122,9 +122,11 @@ export class DaytonaSandboxProvider
|
|
|
122
122
|
async get(sandboxId: string): Promise<DaytonaSandbox> {
|
|
123
123
|
try {
|
|
124
124
|
const sdkSandbox = await this.client.get(sandboxId);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
return new DaytonaSandboxImpl(
|
|
126
|
+
sdkSandbox.id,
|
|
127
|
+
sdkSandbox,
|
|
128
|
+
this.defaultWorkspaceBase
|
|
129
|
+
);
|
|
128
130
|
} catch {
|
|
129
131
|
throw new SandboxNotFoundError(sandboxId);
|
|
130
132
|
}
|
|
@@ -134,7 +136,6 @@ export class DaytonaSandboxProvider
|
|
|
134
136
|
try {
|
|
135
137
|
const sdkSandbox = await this.client.get(sandboxId);
|
|
136
138
|
await this.client.delete(sdkSandbox);
|
|
137
|
-
this.workspaceBaseById.delete(sandboxId);
|
|
138
139
|
} catch {
|
|
139
140
|
// Already gone
|
|
140
141
|
}
|
|
@@ -142,13 +143,13 @@ export class DaytonaSandboxProvider
|
|
|
142
143
|
|
|
143
144
|
async snapshot(_sandboxId: string): Promise<SandboxSnapshot> {
|
|
144
145
|
throw new SandboxNotSupportedError(
|
|
145
|
-
"snapshot (use Daytona's native snapshot API directly)"
|
|
146
|
+
"snapshot (use Daytona's native snapshot API directly)"
|
|
146
147
|
);
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
async restore(_snapshot: SandboxSnapshot): Promise<never> {
|
|
150
151
|
throw new SandboxNotSupportedError(
|
|
151
|
-
"restore (use Daytona's native snapshot API directly)"
|
|
152
|
+
"restore (use Daytona's native snapshot API directly)"
|
|
152
153
|
);
|
|
153
154
|
}
|
|
154
155
|
}
|
|
@@ -34,22 +34,26 @@ export interface LangChainThreadManager extends BaseThreadManager<StoredMessage>
|
|
|
34
34
|
createSystemMessage(content: string): StoredMessage;
|
|
35
35
|
createAIMessage(
|
|
36
36
|
content: string | MessageContent,
|
|
37
|
-
kwargs?: { header?: string; options?: string[]; multiSelect?: boolean }
|
|
37
|
+
kwargs?: { header?: string; options?: string[]; multiSelect?: boolean }
|
|
38
38
|
): StoredMessage;
|
|
39
39
|
createToolMessage(
|
|
40
40
|
content: LangChainToolMessageContent,
|
|
41
|
-
toolCallId: string
|
|
41
|
+
toolCallId: string
|
|
42
42
|
): StoredMessage;
|
|
43
43
|
appendHumanMessage(content: string | MessageContent): Promise<void>;
|
|
44
44
|
appendSystemMessage(content: string): Promise<void>;
|
|
45
45
|
appendToolMessage(
|
|
46
46
|
content: LangChainToolMessageContent,
|
|
47
|
-
toolCallId: string
|
|
47
|
+
toolCallId: string
|
|
48
48
|
): Promise<void>;
|
|
49
49
|
appendAIMessage(content: string | MessageContent): Promise<void>;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function storedMessageId(msg: StoredMessage): string {
|
|
53
|
+
if (msg.type === "tool") {
|
|
54
|
+
return msg.data.tool_call_id ?? "";
|
|
55
|
+
}
|
|
56
|
+
|
|
53
57
|
return msg.data.id ?? "";
|
|
54
58
|
}
|
|
55
59
|
|
|
@@ -59,7 +63,7 @@ function storedMessageId(msg: StoredMessage): string {
|
|
|
59
63
|
* appending typed LangChain messages.
|
|
60
64
|
*/
|
|
61
65
|
export function createLangChainThreadManager(
|
|
62
|
-
config: LangChainThreadManagerConfig
|
|
66
|
+
config: LangChainThreadManagerConfig
|
|
63
67
|
): LangChainThreadManager {
|
|
64
68
|
const baseConfig: ThreadManagerConfig<StoredMessage> = {
|
|
65
69
|
redis: config.redis,
|
|
@@ -87,7 +91,7 @@ export function createLangChainThreadManager(
|
|
|
87
91
|
|
|
88
92
|
createAIMessage(
|
|
89
93
|
content: string,
|
|
90
|
-
kwargs?: { header?: string; options?: string[]; multiSelect?: boolean }
|
|
94
|
+
kwargs?: { header?: string; options?: string[]; multiSelect?: boolean }
|
|
91
95
|
): StoredMessage {
|
|
92
96
|
return new AIMessage({
|
|
93
97
|
id: uuidv4(),
|
|
@@ -104,7 +108,7 @@ export function createLangChainThreadManager(
|
|
|
104
108
|
|
|
105
109
|
createToolMessage(
|
|
106
110
|
content: LangChainToolMessageContent,
|
|
107
|
-
toolCallId: string
|
|
111
|
+
toolCallId: string
|
|
108
112
|
): StoredMessage {
|
|
109
113
|
return new ToolMessage({
|
|
110
114
|
id: uuidv4(),
|
|
@@ -120,7 +124,7 @@ export function createLangChainThreadManager(
|
|
|
120
124
|
|
|
121
125
|
async appendToolMessage(
|
|
122
126
|
content: LangChainToolMessageContent,
|
|
123
|
-
toolCallId: string
|
|
127
|
+
toolCallId: string
|
|
124
128
|
): Promise<void> {
|
|
125
129
|
const message = helpers.createToolMessage(content, toolCallId);
|
|
126
130
|
await base.append([message]);
|
|
@@ -5,6 +5,7 @@ import type { ThreadOps } from "./types";
|
|
|
5
5
|
import type { RunAgentActivity } from "../model/types";
|
|
6
6
|
import type { RawToolCall } from "../tool-router/types";
|
|
7
7
|
import type { SandboxOps } from "../sandbox/types";
|
|
8
|
+
import type { ActivityInterfaceFor } from "@temporalio/workflow";
|
|
8
9
|
|
|
9
10
|
let idCounter = 0;
|
|
10
11
|
|
|
@@ -51,9 +52,26 @@ type TurnScript = {
|
|
|
51
52
|
usage?: TokenUsage;
|
|
52
53
|
};
|
|
53
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Wraps every method on a ThreadOps object so it also has `.executeWithOptions()`,
|
|
57
|
+
* matching Temporal's `ActivityInterfaceFor<ThreadOps>` shape.
|
|
58
|
+
*/
|
|
59
|
+
function toActivityInterface(
|
|
60
|
+
raw: ThreadOps,
|
|
61
|
+
): ActivityInterfaceFor<ThreadOps> {
|
|
62
|
+
const result = {} as Record<string, unknown>;
|
|
63
|
+
for (const [key, fn] of Object.entries(raw)) {
|
|
64
|
+
const wrapped = (...args: unknown[]) => (fn as (...a: unknown[]) => unknown)(...args);
|
|
65
|
+
wrapped.executeWithOptions = (_opts: unknown, args: unknown[]) =>
|
|
66
|
+
(fn as (...a: unknown[]) => unknown)(...args);
|
|
67
|
+
result[key] = wrapped;
|
|
68
|
+
}
|
|
69
|
+
return result as ActivityInterfaceFor<ThreadOps>;
|
|
70
|
+
}
|
|
71
|
+
|
|
54
72
|
function createMockThreadOps() {
|
|
55
73
|
const log: { op: string; args: unknown[] }[] = [];
|
|
56
|
-
const ops
|
|
74
|
+
const ops = toActivityInterface({
|
|
57
75
|
initializeThread: async (threadId) => {
|
|
58
76
|
log.push({ op: "initializeThread", args: [threadId] });
|
|
59
77
|
},
|
|
@@ -69,7 +87,7 @@ function createMockThreadOps() {
|
|
|
69
87
|
forkThread: async (source, target) => {
|
|
70
88
|
log.push({ op: "forkThread", args: [source, target] });
|
|
71
89
|
},
|
|
72
|
-
};
|
|
90
|
+
});
|
|
73
91
|
return { ops, log };
|
|
74
92
|
}
|
|
75
93
|
|
|
@@ -5,6 +5,7 @@ import type { ThreadOps } from "./types";
|
|
|
5
5
|
import type { RunAgentActivity } from "../model/types";
|
|
6
6
|
import type { RawToolCall } from "../tool-router/types";
|
|
7
7
|
import type { SandboxOps } from "../sandbox/types";
|
|
8
|
+
import type { ActivityInterfaceFor } from "@temporalio/workflow";
|
|
8
9
|
|
|
9
10
|
// ---------------------------------------------------------------------------
|
|
10
11
|
// Mock @temporalio/workflow
|
|
@@ -58,10 +59,23 @@ function at<T>(arr: T[], index: number): T {
|
|
|
58
59
|
return val;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
function toActivityInterface(
|
|
63
|
+
raw: ThreadOps,
|
|
64
|
+
): ActivityInterfaceFor<ThreadOps> {
|
|
65
|
+
const result = {} as Record<string, unknown>;
|
|
66
|
+
for (const [key, fn] of Object.entries(raw)) {
|
|
67
|
+
const wrapped = (...args: unknown[]) => (fn as (...a: unknown[]) => unknown)(...args);
|
|
68
|
+
wrapped.executeWithOptions = (_opts: unknown, args: unknown[]) =>
|
|
69
|
+
(fn as (...a: unknown[]) => unknown)(...args);
|
|
70
|
+
result[key] = wrapped;
|
|
71
|
+
}
|
|
72
|
+
return result as ActivityInterfaceFor<ThreadOps>;
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
function createMockThreadOps() {
|
|
62
76
|
const log: { op: string; args: unknown[] }[] = [];
|
|
63
77
|
|
|
64
|
-
const ops
|
|
78
|
+
const ops = toActivityInterface({
|
|
65
79
|
initializeThread: async (threadId) => {
|
|
66
80
|
log.push({ op: "initializeThread", args: [threadId] });
|
|
67
81
|
},
|
|
@@ -77,7 +91,7 @@ function createMockThreadOps() {
|
|
|
77
91
|
forkThread: async (source, target) => {
|
|
78
92
|
log.push({ op: "forkThread", args: [source, target] });
|
|
79
93
|
},
|
|
80
|
-
};
|
|
94
|
+
});
|
|
81
95
|
|
|
82
96
|
return { ops, log };
|
|
83
97
|
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
defineUpdate,
|
|
5
5
|
setHandler,
|
|
6
6
|
ApplicationFailure,
|
|
7
|
+
type ActivityInterfaceFor,
|
|
7
8
|
} from "@temporalio/workflow";
|
|
8
9
|
import type { SessionExitReason, MessageContent } from "../types";
|
|
9
10
|
import type { ThreadOps, SessionConfig, ZeitlichSession } from "./types";
|
|
@@ -299,7 +300,7 @@ export const createSession = async <T extends ToolMap, M = unknown>({
|
|
|
299
300
|
*/
|
|
300
301
|
export function proxyDefaultThreadOps(
|
|
301
302
|
options?: Parameters<typeof proxyActivities>[0]
|
|
302
|
-
): ThreadOps {
|
|
303
|
+
): ActivityInterfaceFor<ThreadOps> {
|
|
303
304
|
return proxyActivities<ThreadOps>(
|
|
304
305
|
options ?? {
|
|
305
306
|
startToCloseTimeout: "10s",
|
package/src/lib/session/types.ts
CHANGED
|
@@ -15,6 +15,7 @@ import type { Skill } from "../skills/types";
|
|
|
15
15
|
import type { SandboxOps } from "../sandbox/types";
|
|
16
16
|
import type { RunAgentActivity } from "../model/types";
|
|
17
17
|
import type { AgentStateManager, JsonSerializable } from "../state/types";
|
|
18
|
+
import type { ActivityInterfaceFor } from "@temporalio/workflow";
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Thread operations required by a session.
|
|
@@ -53,7 +54,7 @@ export interface SessionConfig<T extends ToolMap, M = unknown> {
|
|
|
53
54
|
/** Workflow-specific runAgent activity (with tools pre-bound) */
|
|
54
55
|
runAgent: RunAgentActivity<M>;
|
|
55
56
|
/** Thread operations (initialize, append messages, parse tool calls) */
|
|
56
|
-
threadOps?: ThreadOps
|
|
57
|
+
threadOps?: ActivityInterfaceFor<ThreadOps>;
|
|
57
58
|
/** Tool router for processing tool calls (optional if agent has no tools) */
|
|
58
59
|
tools?: T;
|
|
59
60
|
/** Subagent configurations */
|
|
@@ -89,7 +89,7 @@ export function createSubagentHandler<
|
|
|
89
89
|
if (config.allowThreadContinuation && childThreadId) {
|
|
90
90
|
finalToolResponse =
|
|
91
91
|
typeof toolResponse === "string"
|
|
92
|
-
? `${toolResponse}\n\n[Thread ID: ${childThreadId}]`
|
|
92
|
+
? `${toolResponse}\n\n[${config.agentName} Thread ID: ${childThreadId}]`
|
|
93
93
|
: toolResponse;
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -39,15 +39,9 @@ export function buildSubagentRegistration(
|
|
|
39
39
|
|
|
40
40
|
return {
|
|
41
41
|
name: SUBAGENT_TOOL_NAME,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
get description(): string {
|
|
46
|
-
return createSubagentTool(getEnabled()).description;
|
|
47
|
-
},
|
|
48
|
-
get schema(): z.ZodObject<z.ZodRawShape> {
|
|
49
|
-
return createSubagentTool(getEnabled()).schema;
|
|
50
|
-
},
|
|
42
|
+
enabled: (): boolean => getEnabled().length > 0,
|
|
43
|
+
description: (): string => createSubagentTool(getEnabled()).description,
|
|
44
|
+
schema: (): z.ZodObject<z.ZodRawShape> => createSubagentTool(getEnabled()).schema,
|
|
51
45
|
handler: createSubagentHandler(subagents),
|
|
52
46
|
...(subagentHooksMap.size > 0 && {
|
|
53
47
|
hooks: {
|
|
@@ -397,10 +397,10 @@ describe("buildSubagentRegistration", () => {
|
|
|
397
397
|
|
|
398
398
|
expect(reg).toBeDefined();
|
|
399
399
|
if (!reg) return;
|
|
400
|
-
expect(reg.enabled).toBe(true);
|
|
400
|
+
expect((reg.enabled as () => boolean)()).toBe(true);
|
|
401
401
|
|
|
402
402
|
flag = false;
|
|
403
|
-
expect(reg.enabled).toBe(false);
|
|
403
|
+
expect((reg.enabled as () => boolean)()).toBe(false);
|
|
404
404
|
});
|
|
405
405
|
|
|
406
406
|
it("disabled when all subagents are disabled", () => {
|
|
@@ -415,7 +415,7 @@ describe("buildSubagentRegistration", () => {
|
|
|
415
415
|
|
|
416
416
|
expect(reg).toBeDefined();
|
|
417
417
|
if (reg) {
|
|
418
|
-
expect(reg.enabled).toBe(false);
|
|
418
|
+
expect((reg.enabled as () => boolean)()).toBe(false);
|
|
419
419
|
}
|
|
420
420
|
});
|
|
421
421
|
|
|
@@ -476,13 +476,14 @@ describe("buildSubagentRegistration", () => {
|
|
|
476
476
|
|
|
477
477
|
expect(reg).toBeDefined();
|
|
478
478
|
if (reg) {
|
|
479
|
-
|
|
480
|
-
expect(
|
|
479
|
+
const desc = reg.description as () => string;
|
|
480
|
+
expect(desc()).toContain("Agent A");
|
|
481
|
+
expect(desc()).toContain("Agent B");
|
|
481
482
|
|
|
482
483
|
bEnabled = false;
|
|
483
484
|
|
|
484
|
-
expect(
|
|
485
|
-
expect(
|
|
485
|
+
expect(desc()).toContain("Agent A");
|
|
486
|
+
expect(desc()).not.toContain("Agent B");
|
|
486
487
|
}
|
|
487
488
|
});
|
|
488
489
|
});
|
|
@@ -519,10 +520,10 @@ describe("defineSubagent", () => {
|
|
|
519
520
|
const reg = buildSubagentRegistration([config]);
|
|
520
521
|
expect(reg).toBeDefined();
|
|
521
522
|
if (!reg) return;
|
|
522
|
-
expect(reg.enabled).toBe(true);
|
|
523
|
+
expect((reg.enabled as () => boolean)()).toBe(true);
|
|
523
524
|
|
|
524
525
|
flag = false;
|
|
525
|
-
expect(reg.enabled).toBe(false);
|
|
526
|
+
expect((reg.enabled as () => boolean)()).toBe(false);
|
|
526
527
|
});
|
|
527
528
|
});
|
|
528
529
|
|
package/src/lib/subagent/tool.ts
CHANGED
|
@@ -57,7 +57,7 @@ export function createSubagentTool<T extends SubagentConfig[]>(
|
|
|
57
57
|
.string()
|
|
58
58
|
.nullable()
|
|
59
59
|
.describe(
|
|
60
|
-
"Thread ID to continue an existing conversation, or null to start a new one"
|
|
60
|
+
"Thread ID to continue an existing conversation from the same subagent, or null to start a new one"
|
|
61
61
|
),
|
|
62
62
|
})
|
|
63
63
|
: z.object(baseFields);
|
package/src/lib/thread/index.ts
CHANGED
|
@@ -38,9 +38,14 @@ import type { ToolResultConfig } from "../types";
|
|
|
38
38
|
|
|
39
39
|
function createAppendSpy() {
|
|
40
40
|
const calls: ToolResultConfig[] = [];
|
|
41
|
-
const fn
|
|
42
|
-
calls.push(config);
|
|
43
|
-
|
|
41
|
+
const fn = Object.assign(
|
|
42
|
+
async (config: ToolResultConfig) => { calls.push(config); },
|
|
43
|
+
{ executeWithOptions: (_opts: unknown, [config]: [ToolResultConfig]) => {
|
|
44
|
+
calls.push(config);
|
|
45
|
+
return Promise.resolve();
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
) as AppendToolResultFn;
|
|
44
49
|
return { fn, calls };
|
|
45
50
|
}
|
|
46
51
|
|
|
@@ -86,9 +86,14 @@ function createTools() {
|
|
|
86
86
|
|
|
87
87
|
function createAppendSpy() {
|
|
88
88
|
const calls: ToolResultConfig[] = [];
|
|
89
|
-
const fn
|
|
90
|
-
calls.push(config);
|
|
91
|
-
|
|
89
|
+
const fn = Object.assign(
|
|
90
|
+
async (config: ToolResultConfig) => { calls.push(config); },
|
|
91
|
+
{ executeWithOptions: (_opts: unknown, [config]: [ToolResultConfig]) => {
|
|
92
|
+
calls.push(config);
|
|
93
|
+
return Promise.resolve();
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
) as AppendToolResultFn;
|
|
92
97
|
return { fn, calls };
|
|
93
98
|
}
|
|
94
99
|
|