@capekai/core 1.0.5 → 1.0.7
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/package.json +2 -2
- package/src/adapters/ai-sdk.ts +4 -2
- package/src/core/agent.ts +3 -2
- package/src/core/build-tools.ts +3 -0
- package/src/core/chat-handler.ts +19 -4
- package/src/core/model-utils.ts +5 -1
- package/src/core/provider-utils.ts +4 -0
- package/src/core/tool-builders/external-tools.ts +11 -2
- package/src/internal/hosts.ts +2 -0
- package/src/providers/types.ts +1 -0
- package/src/runtime/host-dependencies.ts +34 -1
- package/src/runtime/host.ts +29 -2
- package/src/subagent/child-session.ts +18 -5
- package/src/subagent/task-tool.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capekai/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Bun-native composable agent runtime and framework for Capek.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"@ai-sdk/deepseek": "^2.0.35",
|
|
79
79
|
"@ai-sdk/openai": "^3.0.84",
|
|
80
80
|
"@capekai/tool": "^1.0.3",
|
|
81
|
-
"@capekai/types": "^1.0.
|
|
81
|
+
"@capekai/types": "^1.0.3",
|
|
82
82
|
"@openrouter/ai-sdk-provider": "^2.3.3",
|
|
83
83
|
"@zip.js/zip.js": "^2.7.60",
|
|
84
84
|
"ai": "^6.0.116",
|
package/src/adapters/ai-sdk.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type Tool,
|
|
9
9
|
} from 'ai';
|
|
10
10
|
import { getModelWithMetadata } from '../core/model-utils';
|
|
11
|
+
import { openAiModelOmitsTemperature } from '../core/provider-utils';
|
|
11
12
|
import type { ModelFactoryResult } from '../providers/types';
|
|
12
13
|
|
|
13
14
|
export interface TextModelRequest {
|
|
@@ -21,7 +22,7 @@ export interface TextModelRequest {
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export async function runTextModel(request: TextModelRequest): Promise<string> {
|
|
24
|
-
const { model, omitMaxOutputTokens, providerOptions, useProviderInstructions } = await getModelWithMetadata({
|
|
25
|
+
const { model, omitMaxOutputTokens, omitTemperature, providerOptions, useProviderInstructions } = await getModelWithMetadata({
|
|
25
26
|
modelId: request.modelId,
|
|
26
27
|
providerId: request.providerId,
|
|
27
28
|
systemPrompt: request.systemPrompt,
|
|
@@ -34,7 +35,7 @@ export async function runTextModel(request: TextModelRequest): Promise<string> {
|
|
|
34
35
|
...(omitMaxOutputTokens || request.maxOutputTokens === undefined
|
|
35
36
|
? {}
|
|
36
37
|
: { maxOutputTokens: request.maxOutputTokens }),
|
|
37
|
-
temperature: request.temperature,
|
|
38
|
+
...(omitTemperature ? {} : { temperature: request.temperature }),
|
|
38
39
|
providerOptions: providerOptions as Parameters<typeof streamText>[0]['providerOptions'],
|
|
39
40
|
});
|
|
40
41
|
return stream.text;
|
|
@@ -57,6 +58,7 @@ export function createOpenAiResponsesModel(request: OpenAiResponsesModelRequest)
|
|
|
57
58
|
model: openai.responses(request.modelId) as unknown as LanguageModel,
|
|
58
59
|
useProviderInstructions: true,
|
|
59
60
|
omitMaxOutputTokens: true,
|
|
61
|
+
omitTemperature: openAiModelOmitsTemperature(request.modelId),
|
|
60
62
|
providerOptions: {
|
|
61
63
|
openai: {
|
|
62
64
|
instructions: request.systemPrompt || 'You are a helpful assistant.',
|
package/src/core/agent.ts
CHANGED
|
@@ -121,6 +121,7 @@ export async function* streamChat(options: ChatOptions): AsyncGenerator<MessageE
|
|
|
121
121
|
broadcastFn: options.broadcastFn,
|
|
122
122
|
additionalPaths: effectiveAdditionalPaths,
|
|
123
123
|
agentId: preconfig.id,
|
|
124
|
+
workspaceRootId: session?.workspaceRootId ?? undefined,
|
|
124
125
|
});
|
|
125
126
|
|
|
126
127
|
const selfDelegationAvailable = Boolean(aiTools.task)
|
|
@@ -140,7 +141,7 @@ export async function* streamChat(options: ChatOptions): AsyncGenerator<MessageE
|
|
|
140
141
|
selfDelegationAvailable,
|
|
141
142
|
});
|
|
142
143
|
|
|
143
|
-
const { model, useProviderInstructions, omitMaxOutputTokens, providerOptions: baseProviderOptions } =
|
|
144
|
+
const { model, useProviderInstructions, omitMaxOutputTokens, omitTemperature, providerOptions: baseProviderOptions } =
|
|
144
145
|
await getModelWithMetadata({
|
|
145
146
|
modelId: resolvedModelId,
|
|
146
147
|
providerId,
|
|
@@ -198,7 +199,7 @@ export async function* streamChat(options: ChatOptions): AsyncGenerator<MessageE
|
|
|
198
199
|
tools: aiTools,
|
|
199
200
|
maxOutputTokens: omitMaxOutputTokens ? undefined : getMaxOutputTokens(resolvedModelId),
|
|
200
201
|
providerOptions: streamConfig.providerOptions as Parameters<typeof streamText>[0]['providerOptions'],
|
|
201
|
-
temperature: streamConfig.temperature,
|
|
202
|
+
...(omitTemperature ? {} : { temperature: streamConfig.temperature }),
|
|
202
203
|
stopWhen: stepCountIs(streamConfig.maxSteps),
|
|
203
204
|
abortSignal: abortController.signal,
|
|
204
205
|
experimental_onStepStart,
|
package/src/core/build-tools.ts
CHANGED
|
@@ -33,6 +33,7 @@ export interface BuildToolsOptions {
|
|
|
33
33
|
broadcastFn?: AskBroadcastFn;
|
|
34
34
|
additionalPaths?: string[];
|
|
35
35
|
agentId?: string | null;
|
|
36
|
+
workspaceRootId?: string;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
export async function buildAiSdkTools(
|
|
@@ -53,6 +54,7 @@ export async function buildAiSdkTools(
|
|
|
53
54
|
broadcastFn,
|
|
54
55
|
additionalPaths,
|
|
55
56
|
agentId,
|
|
57
|
+
workspaceRootId,
|
|
56
58
|
} = options;
|
|
57
59
|
|
|
58
60
|
// Resolve root session ID by walking up the parent chain
|
|
@@ -92,6 +94,7 @@ export async function buildAiSdkTools(
|
|
|
92
94
|
modelId,
|
|
93
95
|
providerId,
|
|
94
96
|
additionalPaths,
|
|
97
|
+
workspaceRootId,
|
|
95
98
|
});
|
|
96
99
|
const tools: ToolMap = { ...externalTools };
|
|
97
100
|
|
package/src/core/chat-handler.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
isDefaultSessionTitle,
|
|
7
7
|
isSandboxActive,
|
|
8
8
|
emitTerminal,
|
|
9
|
+
resolveSessionWorkspace,
|
|
9
10
|
} from '../runtime/host-dependencies';
|
|
10
11
|
import { getDefaultPreconfig, getPreconfigOrAgent } from '../context';
|
|
11
12
|
import {
|
|
@@ -552,8 +553,15 @@ export async function handleChat<Origin>(
|
|
|
552
553
|
}
|
|
553
554
|
|
|
554
555
|
const workspace = session.workspaceId ? await getWorkspace(session.workspaceId) : null;
|
|
555
|
-
const
|
|
556
|
-
|
|
556
|
+
const workspaceContext = await resolveSessionWorkspace({
|
|
557
|
+
sessionId,
|
|
558
|
+
workspaceId: session.workspaceId || undefined,
|
|
559
|
+
workspaceRootId: session.workspaceRootId ?? undefined,
|
|
560
|
+
workspacePath: workspace?.path,
|
|
561
|
+
additionalPaths: workspace?.additionalPaths,
|
|
562
|
+
});
|
|
563
|
+
const workspacePath = workspaceContext.workspacePath;
|
|
564
|
+
const additionalPaths = workspaceContext.additionalPaths;
|
|
557
565
|
|
|
558
566
|
const preconfig = session.preconfigId
|
|
559
567
|
? await getPreconfigOrAgent(session.preconfigId)
|
|
@@ -810,8 +818,15 @@ export async function handleSessionEditMessage<Origin>(
|
|
|
810
818
|
});
|
|
811
819
|
|
|
812
820
|
const workspace = session.workspaceId ? await getWorkspace(session.workspaceId) : null;
|
|
813
|
-
const
|
|
814
|
-
|
|
821
|
+
const workspaceContext = await resolveSessionWorkspace({
|
|
822
|
+
sessionId: msg.sessionId,
|
|
823
|
+
workspaceId: session.workspaceId || undefined,
|
|
824
|
+
workspaceRootId: session.workspaceRootId ?? undefined,
|
|
825
|
+
workspacePath: workspace?.path,
|
|
826
|
+
additionalPaths: workspace?.additionalPaths,
|
|
827
|
+
});
|
|
828
|
+
const workspacePath = workspaceContext.workspacePath;
|
|
829
|
+
const additionalPaths = workspaceContext.additionalPaths;
|
|
815
830
|
|
|
816
831
|
const preconfig = session.preconfigId
|
|
817
832
|
? await getPreconfigOrAgent(session.preconfigId)
|
package/src/core/model-utils.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type LanguageModel } from 'ai';
|
|
2
2
|
import { createOpenAI } from '@ai-sdk/openai';
|
|
3
|
-
import { findProviderFromModel, parseModelSpecifier } from './provider-utils';
|
|
3
|
+
import { findProviderFromModel, openAiModelOmitsTemperature, parseModelSpecifier } from './provider-utils';
|
|
4
4
|
import { findModel, getApiKeyForProvider, getLLMBaseUrl, getModelsConfig } from '../configuration/runtime';
|
|
5
5
|
import { createModelForProvider, getProvider } from '../providers/registry';
|
|
6
6
|
import { isSandboxActive } from '../runtime/host-dependencies';
|
|
@@ -9,6 +9,7 @@ export interface ModelWithMetadata {
|
|
|
9
9
|
model: LanguageModel;
|
|
10
10
|
useProviderInstructions?: boolean;
|
|
11
11
|
omitMaxOutputTokens?: boolean;
|
|
12
|
+
omitTemperature?: boolean;
|
|
12
13
|
providerOptions?: Record<string, Record<string, unknown>>;
|
|
13
14
|
}
|
|
14
15
|
|
|
@@ -46,6 +47,7 @@ export async function getModelWithMetadata(
|
|
|
46
47
|
model: result.model,
|
|
47
48
|
useProviderInstructions: result.useProviderInstructions,
|
|
48
49
|
omitMaxOutputTokens: result.omitMaxOutputTokens,
|
|
50
|
+
omitTemperature: result.omitTemperature,
|
|
49
51
|
providerOptions: result.providerOptions,
|
|
50
52
|
};
|
|
51
53
|
}
|
|
@@ -77,6 +79,7 @@ export async function getModelWithMetadata(
|
|
|
77
79
|
model: result.model,
|
|
78
80
|
useProviderInstructions: result.useProviderInstructions,
|
|
79
81
|
omitMaxOutputTokens: result.omitMaxOutputTokens,
|
|
82
|
+
omitTemperature: result.omitTemperature,
|
|
80
83
|
providerOptions: result.providerOptions,
|
|
81
84
|
};
|
|
82
85
|
}
|
|
@@ -132,6 +135,7 @@ export async function getModelWithMetadata(
|
|
|
132
135
|
});
|
|
133
136
|
return {
|
|
134
137
|
model: openai.responses(model) as unknown as LanguageModel,
|
|
138
|
+
omitTemperature: openAiModelOmitsTemperature(model),
|
|
135
139
|
providerOptions: {
|
|
136
140
|
openai: {
|
|
137
141
|
promptCacheKey: options.sessionId,
|
|
@@ -19,6 +19,10 @@ const PROVIDER_PREFIXES: Array<{ test: (m: string) => boolean; provider: string
|
|
|
19
19
|
{ test: (m) => m.startsWith('deepseek-'), provider: 'deepseek' },
|
|
20
20
|
];
|
|
21
21
|
|
|
22
|
+
export function openAiModelOmitsTemperature(modelId: string): boolean {
|
|
23
|
+
return modelId.startsWith('gpt-6');
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
export interface ParsedModelSpecifier {
|
|
23
27
|
modelId: string;
|
|
24
28
|
providerId?: string;
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from '../../runtime/domain-tool-source';
|
|
20
20
|
import { isToolAllowedInContext, type ToolExecutionScope } from '../tool-capabilities';
|
|
21
21
|
import type { ToolMap } from './types';
|
|
22
|
-
import type
|
|
22
|
+
import { resolveToolDefinition, type BroadcastFn } from '../../runtime/host-dependencies';
|
|
23
23
|
import {
|
|
24
24
|
capekToolOutputToAiSdk,
|
|
25
25
|
createCapekToolOutputEnvelope,
|
|
@@ -39,6 +39,7 @@ export interface ExternalToolsOptions {
|
|
|
39
39
|
modelId?: string;
|
|
40
40
|
providerId?: string;
|
|
41
41
|
additionalPaths?: string[];
|
|
42
|
+
workspaceRootId?: string;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
export async function buildExternalTools(options: ExternalToolsOptions): Promise<ToolMap> {
|
|
@@ -56,6 +57,7 @@ export async function buildExternalTools(options: ExternalToolsOptions): Promise
|
|
|
56
57
|
modelId,
|
|
57
58
|
providerId,
|
|
58
59
|
additionalPaths,
|
|
60
|
+
workspaceRootId,
|
|
59
61
|
} = options;
|
|
60
62
|
|
|
61
63
|
const tools: ToolMap = {};
|
|
@@ -83,7 +85,14 @@ export async function buildExternalTools(options: ExternalToolsOptions): Promise
|
|
|
83
85
|
const loadedTool = await getTool(name);
|
|
84
86
|
if (!loadedTool) continue;
|
|
85
87
|
|
|
86
|
-
const
|
|
88
|
+
const definition = await resolveToolDefinition({
|
|
89
|
+
sessionId,
|
|
90
|
+
workspaceId,
|
|
91
|
+
workspaceRootId,
|
|
92
|
+
workspacePath,
|
|
93
|
+
definition: loadedTool.definition,
|
|
94
|
+
});
|
|
95
|
+
if (!definition) continue;
|
|
87
96
|
|
|
88
97
|
if (!isToolAllowedInContext(definition.capabilities, executionScopes)) {
|
|
89
98
|
continue;
|
package/src/internal/hosts.ts
CHANGED
|
@@ -22,7 +22,9 @@ export {
|
|
|
22
22
|
type PermissionRequestStatus,
|
|
23
23
|
type RuntimeHost,
|
|
24
24
|
type SandboxBindings,
|
|
25
|
+
type SessionWorkspaceContext,
|
|
25
26
|
type TitleHost,
|
|
27
|
+
type ToolPolicyHost,
|
|
26
28
|
type WorkspaceCapabilityBindings,
|
|
27
29
|
} from '../runtime/host';
|
|
28
30
|
export { createStandaloneHost } from '../runtime/standalone-host';
|
package/src/providers/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Session } from '@capekai/types';
|
|
2
|
-
import {
|
|
2
|
+
import type { ToolDefinition } from '@capekai/tool';
|
|
3
|
+
import { getOptionalRuntimeHost, getRuntimeHost } from './host';
|
|
3
4
|
import type { RuntimeAudience, RuntimeDelivery, RuntimeEvent } from './events';
|
|
4
5
|
|
|
5
6
|
type HostRuntimeAudience = Exclude<RuntimeAudience, { scope: 'origin' }>;
|
|
@@ -66,6 +67,38 @@ export const generateSessionTitle = (...args: Parameters<ReturnType<typeof getRu
|
|
|
66
67
|
getRuntimeHost().titles.generateSessionTitle(...args);
|
|
67
68
|
export const getToolWorkspaceHost = (...args: Parameters<ReturnType<typeof getRuntimeHost>['workspace']['createToolWorkspaceHost']>) =>
|
|
68
69
|
getRuntimeHost().workspace.createToolWorkspaceHost(...args);
|
|
70
|
+
|
|
71
|
+
export async function resolveSessionWorkspace(options: {
|
|
72
|
+
sessionId: string;
|
|
73
|
+
workspaceId?: string;
|
|
74
|
+
workspaceRootId?: string;
|
|
75
|
+
workspacePath?: string;
|
|
76
|
+
additionalPaths?: string[];
|
|
77
|
+
}): Promise<{ workspacePath?: string; additionalPaths?: string[] }> {
|
|
78
|
+
const resolver = getRuntimeHost().workspace.resolveSessionWorkspace;
|
|
79
|
+
if (resolver) {
|
|
80
|
+
return await resolver(options);
|
|
81
|
+
}
|
|
82
|
+
if (options.workspaceRootId) {
|
|
83
|
+
throw new Error('Session workspace root requires a host resolver');
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
workspacePath: options.workspacePath,
|
|
87
|
+
additionalPaths: options.additionalPaths,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function resolveToolDefinition(options: {
|
|
92
|
+
sessionId: string;
|
|
93
|
+
workspaceId?: string;
|
|
94
|
+
workspaceRootId?: string;
|
|
95
|
+
workspacePath?: string;
|
|
96
|
+
definition: ToolDefinition;
|
|
97
|
+
}): Promise<ToolDefinition | null> {
|
|
98
|
+
const resolver = getOptionalRuntimeHost()?.toolPolicy?.resolveDefinition;
|
|
99
|
+
return resolver ? await resolver(options) : options.definition;
|
|
100
|
+
}
|
|
101
|
+
|
|
69
102
|
export const isSandboxActive = (): boolean => getRuntimeHost().sandbox.isSandboxActive();
|
|
70
103
|
|
|
71
104
|
export type { RuntimeEventSink, RuntimeEventSink as BroadcastFn } from './events';
|
package/src/runtime/host.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
2
|
import type { HostLayout } from './host-layout';
|
|
3
|
-
import type { Ask } from '@capekai/tool';
|
|
3
|
+
import type { Ask, ToolDefinition } from '@capekai/tool';
|
|
4
4
|
import type {
|
|
5
5
|
AskRequestMessage, AskTimedOutMessage, AutoApproveSeverity, MessageWithParts, Session,
|
|
6
6
|
} from '@capekai/types';
|
|
@@ -82,7 +82,19 @@ export interface TitleHost {
|
|
|
82
82
|
generateSessionTitle(messages: MessageWithParts[]): Promise<string | null>;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
export interface SessionWorkspaceContext {
|
|
86
|
+
workspacePath?: string;
|
|
87
|
+
additionalPaths?: string[];
|
|
88
|
+
}
|
|
89
|
+
|
|
85
90
|
export interface WorkspaceCapabilityBindings {
|
|
91
|
+
resolveSessionWorkspace?(options: {
|
|
92
|
+
sessionId: string;
|
|
93
|
+
workspaceId?: string;
|
|
94
|
+
workspaceRootId?: string;
|
|
95
|
+
workspacePath?: string;
|
|
96
|
+
additionalPaths?: string[];
|
|
97
|
+
}): SessionWorkspaceContext | Promise<SessionWorkspaceContext>;
|
|
86
98
|
createToolWorkspaceHost(options: {
|
|
87
99
|
workspaceId?: string;
|
|
88
100
|
workspacePath?: string;
|
|
@@ -91,6 +103,16 @@ export interface WorkspaceCapabilityBindings {
|
|
|
91
103
|
}): WorkspaceCapabilityHost;
|
|
92
104
|
}
|
|
93
105
|
|
|
106
|
+
export interface ToolPolicyHost {
|
|
107
|
+
resolveDefinition?(options: {
|
|
108
|
+
sessionId: string;
|
|
109
|
+
workspaceId?: string;
|
|
110
|
+
workspaceRootId?: string;
|
|
111
|
+
workspacePath?: string;
|
|
112
|
+
definition: ToolDefinition;
|
|
113
|
+
}): ToolDefinition | null | Promise<ToolDefinition | null>;
|
|
114
|
+
}
|
|
115
|
+
|
|
94
116
|
export interface SandboxBindings {
|
|
95
117
|
isSandboxActive(): boolean;
|
|
96
118
|
}
|
|
@@ -100,6 +122,7 @@ export interface RuntimeHost {
|
|
|
100
122
|
delivery: DeliveryHost;
|
|
101
123
|
titles: TitleHost;
|
|
102
124
|
workspace: WorkspaceCapabilityBindings;
|
|
125
|
+
toolPolicy?: ToolPolicyHost;
|
|
103
126
|
sandbox: SandboxBindings;
|
|
104
127
|
/** Host-supplied filesystem layout policy. */
|
|
105
128
|
layout?: HostLayout;
|
|
@@ -122,8 +145,12 @@ export function withRuntimeHost<T>(value: RuntimeHost, callback: () => T): T {
|
|
|
122
145
|
return scopedHost.run(value, callback);
|
|
123
146
|
}
|
|
124
147
|
|
|
148
|
+
export function getOptionalRuntimeHost(): RuntimeHost | null {
|
|
149
|
+
return scopedHost.getStore() ?? host;
|
|
150
|
+
}
|
|
151
|
+
|
|
125
152
|
export function getRuntimeHost(): RuntimeHost {
|
|
126
|
-
const active =
|
|
153
|
+
const active = getOptionalRuntimeHost();
|
|
127
154
|
if (!active) throw new Error('Runtime host has not been configured');
|
|
128
155
|
return active;
|
|
129
156
|
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
emitTerminal,
|
|
6
6
|
emitToAskTargets,
|
|
7
7
|
emitToController,
|
|
8
|
+
resolveSessionWorkspace,
|
|
8
9
|
} from '../runtime/host-dependencies';
|
|
9
10
|
import { getLLMSubagentMaxSteps } from '../configuration/runtime';
|
|
10
11
|
import {
|
|
@@ -59,9 +60,21 @@ export async function executeChildSession(options: {
|
|
|
59
60
|
streamChat = streamChatWithRetry,
|
|
60
61
|
} = options;
|
|
61
62
|
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
// Re-resolve the child session's host-owned root. Async child execution may
|
|
64
|
+
// enter after the parent context was assembled, so the persisted child
|
|
65
|
+
// binding is authoritative.
|
|
66
|
+
const childSession = await getSession(childSessionId);
|
|
67
|
+
const effectiveWorkspaceId = workspaceId ?? childSession?.workspaceId ?? undefined;
|
|
68
|
+
const workspace = effectiveWorkspaceId ? await getWorkspace(effectiveWorkspaceId) : null;
|
|
69
|
+
const workspaceContext = await resolveSessionWorkspace({
|
|
70
|
+
sessionId: childSessionId,
|
|
71
|
+
workspaceId: effectiveWorkspaceId,
|
|
72
|
+
workspaceRootId: childSession?.workspaceRootId ?? undefined,
|
|
73
|
+
workspacePath: workspacePath ?? workspace?.path,
|
|
74
|
+
additionalPaths: workspace?.additionalPaths,
|
|
75
|
+
});
|
|
76
|
+
const effectiveWorkspacePath = workspaceContext.workspacePath;
|
|
77
|
+
const additionalPaths = workspaceContext.additionalPaths;
|
|
65
78
|
|
|
66
79
|
let messages: MessageWithParts[];
|
|
67
80
|
|
|
@@ -172,8 +185,8 @@ export async function executeChildSession(options: {
|
|
|
172
185
|
sessionId: childSessionId,
|
|
173
186
|
preconfig,
|
|
174
187
|
messages,
|
|
175
|
-
workspacePath,
|
|
176
|
-
workspaceId,
|
|
188
|
+
workspacePath: effectiveWorkspacePath,
|
|
189
|
+
workspaceId: effectiveWorkspaceId,
|
|
177
190
|
additionalPaths,
|
|
178
191
|
modelId: modelId ?? undefined,
|
|
179
192
|
providerId: providerId ?? undefined,
|
|
@@ -429,6 +429,7 @@ async function runSubagent(
|
|
|
429
429
|
childSession = await createSessionFn({
|
|
430
430
|
id: randomUUID(),
|
|
431
431
|
workspaceId: workspaceId || parentSession?.workspaceId || '',
|
|
432
|
+
workspaceRootId: parentSession?.workspaceRootId ?? null,
|
|
432
433
|
preconfigId: subagent_type,
|
|
433
434
|
title: `${description} (@${subagent_type} subagent)`,
|
|
434
435
|
status: 'active',
|