Skip to content

Commit a59d33d

Browse files
authored
feat(tarko-agent): runtime settings (#1561)
1 parent 9f6930f commit a59d33d

File tree

12 files changed

+933
-43
lines changed

12 files changed

+933
-43
lines changed

multimodal/tarko/agent-server-next/src/services/session/AgentSession.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ export class AgentSession {
169169
// Log AGIO initialization
170170
console.debug('AGIO collector initialized', { provider: agentOptions.agio.provider });
171171
}
172+
172173
this.logger.info('create new agent with config: ', JSON.stringify({
173174
agent: agentOptions.agent,
174175
share: agentOptions.share,

multimodal/tarko/agent-server/src/api/controllers/sessions.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,127 @@ import { getDefaultModel } from '../../utils/model-utils';
1212
import * as path from 'path';
1313
import * as fs from 'fs';
1414

15+
/**
16+
* Get runtime settings schema and current values
17+
*/
18+
export async function getRuntimeSettings(req: Request, res: Response) {
19+
const sessionId = req.query.sessionId as string;
20+
21+
if (!sessionId) {
22+
return res.status(400).json({ error: 'Session ID is required' });
23+
}
24+
25+
try {
26+
const server = req.app.locals.server;
27+
28+
// Get runtime settings configuration from server config
29+
const runtimeSettingsConfig = server.appConfig?.server?.runtimeSettings;
30+
31+
if (!runtimeSettingsConfig) {
32+
return res.status(200).json({
33+
schema: { type: 'object', properties: {} },
34+
currentValues: {}
35+
});
36+
}
37+
38+
// Get current session info to retrieve stored runtime settings
39+
let currentValues = {};
40+
if (server.storageProvider) {
41+
try {
42+
const sessionInfo = await server.storageProvider.getSessionInfo(sessionId);
43+
currentValues = sessionInfo?.metadata?.runtimeSettings || {};
44+
} catch (error) {
45+
// Session doesn't exist or no stored values, use defaults from schema
46+
}
47+
}
48+
49+
// Merge with default values from schema
50+
const schema = runtimeSettingsConfig.schema;
51+
const mergedValues: Record<string, any> = { ...currentValues };
52+
53+
if (schema.properties) {
54+
Object.entries(schema.properties).forEach(([key, propSchema]: [string, any]) => {
55+
if (mergedValues[key] === undefined && propSchema.default !== undefined) {
56+
mergedValues[key] = propSchema.default;
57+
}
58+
});
59+
}
60+
61+
res.status(200).json({
62+
schema: runtimeSettingsConfig.schema,
63+
currentValues: mergedValues
64+
});
65+
} catch (error) {
66+
console.error(`Error getting runtime settings for session ${sessionId}:`, error);
67+
res.status(500).json({ error: 'Failed to get runtime settings' });
68+
}
69+
}
70+
71+
/**
72+
* Update runtime settings for a session
73+
*/
74+
export async function updateRuntimeSettings(req: Request, res: Response) {
75+
const { sessionId, runtimeSettings } = req.body as {
76+
sessionId: string;
77+
runtimeSettings: Record<string, any>;
78+
};
79+
80+
if (!sessionId) {
81+
return res.status(400).json({ error: 'Session ID is required' });
82+
}
83+
84+
if (!runtimeSettings || typeof runtimeSettings !== 'object') {
85+
return res.status(400).json({ error: 'Runtime settings object is required' });
86+
}
87+
88+
try {
89+
const server = req.app.locals.server;
90+
91+
if (!server.storageProvider) {
92+
return res.status(404).json({ error: 'Storage not configured, cannot update runtime settings' });
93+
}
94+
95+
const sessionInfo = await server.storageProvider.getSessionInfo(sessionId);
96+
if (!sessionInfo) {
97+
return res.status(404).json({ error: 'Session not found' });
98+
}
99+
100+
// Update session info with new runtime settings
101+
const updatedSessionInfo = await server.storageProvider.updateSessionInfo(sessionId, {
102+
metadata: {
103+
...sessionInfo.metadata,
104+
runtimeSettings,
105+
},
106+
});
107+
108+
// If session is currently active, recreate the agent with new runtime settings
109+
const activeSession = server.sessions[sessionId];
110+
if (activeSession) {
111+
console.log('Runtime settings updated', {
112+
sessionId,
113+
runtimeSettings,
114+
});
115+
116+
try {
117+
// Recreate agent with new runtime settings configuration
118+
await activeSession.updateSessionConfig(updatedSessionInfo);
119+
console.log('Session agent recreated with new runtime settings', { sessionId });
120+
} catch (error) {
121+
console.error('Failed to update agent runtime settings for session', { sessionId, error });
122+
// Continue execution - the runtime settings are saved, will apply on next session
123+
}
124+
}
125+
126+
res.status(200).json({
127+
session: updatedSessionInfo,
128+
runtimeSettings
129+
});
130+
} catch (error) {
131+
console.error(`Error updating runtime settings for session ${sessionId}:`, error);
132+
res.status(500).json({ error: 'Failed to update runtime settings' });
133+
}
134+
}
135+
15136
/**
16137
* Get all sessions
17138
*/

multimodal/tarko/agent-server/src/api/controllers/system.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export async function updateSessionModel(req: Request, res: Response) {
8080

8181
try {
8282
// Recreate agent with new model configuration
83-
await activeSession.updateModelConfig(updatedSessionInfo);
83+
await activeSession.updateSessionConfig(updatedSessionInfo);
8484
console.log('Session agent recreated with new model config', { sessionId });
8585
} catch (error) {
8686
console.error('Failed to update agent model config for session', { sessionId, error });

multimodal/tarko/agent-server/src/api/routes/sessions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ export function registerSessionRoutes(app: express.Application): void {
3030
router.get('/status', sessionsController.getSessionStatus);
3131
// Update session metadata
3232
router.post('/update', sessionsController.updateSession);
33+
// Get runtime settings schema
34+
router.get('/runtime-settings', sessionsController.getRuntimeSettings);
35+
// Update runtime settings
36+
router.post('/runtime-settings', sessionsController.updateRuntimeSettings);
3337
// Delete a session
3438
router.post('/delete', sessionsController.deleteSession);
3539
// Generate summary for a session

multimodal/tarko/agent-server/src/core/AgentSession.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,31 @@ export class AgentSession {
131131
: [];
132132

133133
// Create agent options including initial events
134-
const agentOptions = {
134+
const baseAgentOptions = {
135135
...this.server.appConfig,
136136
name: this.server.getCurrentAgentName(),
137137
model: this.resolveModelConfig(sessionInfo),
138138
initialEvents: storedEvents, // 🎯 Pass initial events directly to agent
139139
};
140140

141+
// Apply runtime settings transformation if available
142+
const runtimeSettingsConfig = this.server.appConfig?.server?.runtimeSettings;
143+
let transformedOptions = {};
144+
145+
if (runtimeSettingsConfig?.transform && sessionInfo?.metadata?.runtimeSettings) {
146+
try {
147+
transformedOptions = runtimeSettingsConfig.transform(sessionInfo.metadata.runtimeSettings);
148+
} catch (error) {
149+
console.warn('Failed to apply runtime settings transform:', error);
150+
}
151+
}
152+
153+
// Merge base options with transformed runtime settings
154+
const agentOptions = {
155+
...baseAgentOptions,
156+
...transformedOptions,
157+
};
158+
141159
// Create base agent
142160
const baseAgent = new agentResolution.agentConstructor(agentOptions);
143161

@@ -465,15 +483,15 @@ export class AgentSession {
465483
}
466484

467485
/**
468-
* Store the updated model configuration for this session
469-
* The model will be used in subsequent queries via Agent.run() parameters
470-
* @param sessionInfo Updated session metadata with new model config
486+
* Update session configuration (model and runtime settings)
487+
* The configuration will be used in subsequent queries
488+
* @param sessionInfo Updated session metadata
471489
*/
472-
async updateModelConfig(sessionInfo: SessionInfo): Promise<void> {
490+
async updateSessionConfig(sessionInfo: SessionInfo): Promise<void> {
473491
// Store the session metadata for use in future queries
474492
this.sessionInfo = sessionInfo;
475493

476-
// Recreate agent with new model configuration
494+
// Recreate agent with new configuration
477495
try {
478496
// Clean up current agent and AGIO provider
479497
if (this.agent && typeof this.agent.dispose === 'function') {
@@ -494,6 +512,16 @@ export class AgentSession {
494512
}
495513
}
496514

515+
/**
516+
* Store the updated model configuration for this session
517+
* The model will be used in subsequent queries via Agent.run() parameters
518+
* @param sessionInfo Updated session metadata with new model config
519+
* @deprecated Use updateSessionConfig instead
520+
*/
521+
async updateModelConfig(sessionInfo: SessionInfo): Promise<void> {
522+
return this.updateSessionConfig(sessionInfo);
523+
}
524+
497525
async cleanup() {
498526
// Clear running session for exclusive mode
499527
this.server.clearRunningSession(this.id);

multimodal/tarko/agent-ui/src/common/services/apiService.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,58 @@ class ApiService {
530530
return { success: false };
531531
}
532532
}
533+
534+
async getSessionRuntimeSettings(sessionId: string): Promise<{
535+
schema: Record<string, any> | null;
536+
currentValues: Record<string, any> | null;
537+
message?: string;
538+
}> {
539+
try {
540+
const response = await fetch(
541+
`${API_BASE_URL}/api/v1/sessions/runtime-settings?sessionId=${sessionId}`,
542+
{
543+
method: 'GET',
544+
headers: { 'Content-Type': 'application/json' },
545+
signal: AbortSignal.timeout(3000),
546+
},
547+
);
548+
549+
if (!response.ok) {
550+
throw new Error(`Failed to get session runtime settings: ${response.statusText}`);
551+
}
552+
553+
return await response.json();
554+
} catch (error) {
555+
console.error('Error getting session runtime settings:', error);
556+
return { schema: null, currentValues: null, message: 'Failed to load runtime settings' };
557+
}
558+
}
559+
560+
async updateSessionRuntimeSettings(
561+
sessionId: string,
562+
runtimeSettings: Record<string, any>,
563+
): Promise<{ success: boolean; sessionInfo?: SessionInfo }> {
564+
try {
565+
const response = await fetch(`${API_BASE_URL}/api/v1/sessions/runtime-settings`, {
566+
method: 'POST',
567+
headers: { 'Content-Type': 'application/json' },
568+
body: JSON.stringify({ sessionId, runtimeSettings }),
569+
});
570+
571+
if (!response.ok) {
572+
throw new Error(`Failed to update session runtime settings: ${response.statusText}`);
573+
}
574+
575+
const responseData = await response.json();
576+
return {
577+
success: true,
578+
sessionInfo: responseData.session,
579+
};
580+
} catch (error) {
581+
console.error('Error updating session runtime settings:', error);
582+
return { success: false };
583+
}
584+
}
533585
}
534586

535587
// Export singleton instance

0 commit comments

Comments
 (0)