Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
716960d
Implement migration enhancement interface and UI
lochana-chathura Mar 5, 2026
87299fb
Implement migration ai ehancement orchestrator
lochana-chathura Mar 5, 2026
2657e5d
Implement migration enhacement panel UI
lochana-chathura Mar 5, 2026
463f59e
Fix repeated distribution field in Ballerina.toml
lochana-chathura Mar 5, 2026
0754f60
Improve ai ehenacement experience
lochana-chathura Mar 9, 2026
62727ec
Decouple migration panel from AI chat box
lochana-chathura Mar 9, 2026
08d1607
Improve migration panel operations
lochana-chathura Mar 10, 2026
6a71be3
Revamp migration ai-enhancement DX
lochana-chathura Mar 10, 2026
6ad8f44
Improve ai ehncement error handling
lochana-chathura Mar 10, 2026
33fe8a4
Do ai changes on top of the original source
lochana-chathura Mar 10, 2026
d38e8a3
Improve UX: ai tool stream view, login at wizard level
lochana-chathura Mar 10, 2026
447e088
Implement pause/resume for ai enhancement and minor UI changes
lochana-chathura Mar 12, 2026
c9e911b
Optimize ai enhancement prompt
lochana-chathura Mar 12, 2026
0f812c4
Fix migration source read and tune prompt for better results
lochana-chathura Mar 13, 2026
059485d
Implement post-wizard ai-enhancement triggering
lochana-chathura Mar 17, 2026
859519c
Improve ai enhancement pause/resume functionality
lochana-chathura Mar 17, 2026
6a86eb0
Fix debugging failure with migration tool ai changes
lochana-chathura Mar 25, 2026
50890d1
Merge branch 'release/bi-1.8.x' of https://github.com/wso2/vscode-ext…
lochana-chathura Mar 25, 2026
a6fa6ad
Fix issues after syncing with upstream
lochana-chathura Mar 26, 2026
06bae71
Merge branch 'release/bi-1.8.x' of https://github.com/wso2/vscode-ext…
lochana-chathura Mar 26, 2026
c490abb
Add changes to support new wi-extension
lochana-chathura Mar 30, 2026
145ee13
Improve debug logs in ai enhancement flow
lochana-chathura Apr 2, 2026
8a58817
Make ai enhancements, per project
lochana-chathura Apr 3, 2026
0455ade
Add dedicated debug logger for tracing
lochana-chathura Apr 3, 2026
beabd75
Fix premature wizard completion in multi-package AI enhancement
lochana-chathura Apr 3, 2026
bb74cd0
Implement transcript writer for smooth pause resume
lochana-chathura Apr 3, 2026
b1fa459
Merge branch 'release/bi-1.8.x' of https://github.com/wso2/vscode-ext…
lochana-chathura Apr 3, 2026
9bcb076
Update workspaces/ballerina/ballerina-visualizer/src/views/BI/ImportI…
kanushka Apr 6, 2026
bb8ca3a
Restore integrateCodeToWorkspace for review flow
lochana-chathura Apr 6, 2026
d41bc0a
Correct in-place editing guard for review flow
lochana-chathura Apr 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

import { ImportIntegrationResponse } from "../../interfaces/extended-lang-client";
import { GetMigrationToolsResponse, ImportIntegrationRPCRequest, MigrateRequest, MigrationToolPullRequest, OpenMigrationReportRequest, OpenSubProjectReportRequest, SaveMigrationReportRequest, StoreSubProjectReportsRequest } from "./interfaces";
import { ActiveMigrationSession, GetMigrationToolsResponse, ImportIntegrationRPCRequest, MigrateRequest, MigrationToolPullRequest, OpenMigrationReportRequest, OpenSubProjectReportRequest, SaveMigrationReportRequest, StoreSubProjectReportsRequest } from "./interfaces";

export interface MigrateIntegrationAPI {
getMigrationTools: () => Promise<GetMigrationToolsResponse>;
Expand All @@ -28,4 +28,15 @@ export interface MigrateIntegrationAPI {
storeSubProjectReports: (params: StoreSubProjectReportsRequest) => void;
saveMigrationReport: (params: SaveMigrationReportRequest) => void;
migrateProject: (params: MigrateRequest) => void;
getActiveMigrationSession: () => Promise<ActiveMigrationSession>;
/** Starts (or resumes) the AI enhancement pipeline from AI Chat. */
startMigrationEnhancement: () => Promise<void>;
/** Seeds any persisted migration conversation history into the chat state. */
seedMigrationHistory: () => Promise<boolean>;
/** Triggers the wizard-level streaming enhancement pipeline (called from AI Chat after startMigrationEnhancement). */
wizardEnhancementReady: () => Promise<void>;
/** Aborts the currently running migration AI agent. */
abortMigrationAgent: () => Promise<void>;
/** Retrieves the persisted migration conversation history messages for display in AI Chat. */
getMigrationHistoryMessages: () => Promise<Array<{ role: string; content: string }>>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,29 @@ export interface SaveMigrationReportRequest {
};
}

/**
* Describes the current state of a migration AI enhancement session.
* Returned by `getActiveMigrationSession` so the UI can show a live banner.
*/
export interface ActiveMigrationSession {
/** `true` while the enhancement pipeline is running. */
isActive: boolean;
/** `true` when the AI enhancement feature was used (wizard or post-wizard). */
aiFeatureUsed: boolean;
/** `true` once the AI enhancement pipeline has completed successfully. */
fullyEnhanced: boolean;
}

export interface MigrateRequest {
project: ProjectRequest;
textEdits: {
[key: string]: string;
};
projects?: ProjectMigrationResult[];
/** `true` when the AI enhancement feature was used (wizard or post-wizard). */
aiFeatureUsed?: boolean;
/** Absolute path to the original source project (e.g. Mule XML directory). */
sourcePath?: string;
}

export interface OpenSubProjectReportRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* THIS FILE INCLUDES AUTO GENERATED CODE
*/
import { ImportIntegrationResponse } from "../../interfaces/extended-lang-client";
import { GetMigrationToolsResponse, ImportIntegrationRPCRequest, MigrateRequest, MigrationToolPullRequest, OpenMigrationReportRequest, OpenSubProjectReportRequest, SaveMigrationReportRequest, StoreSubProjectReportsRequest } from "./interfaces";
import { ActiveMigrationSession, GetMigrationToolsResponse, ImportIntegrationRPCRequest, MigrateRequest, MigrationToolPullRequest, OpenMigrationReportRequest, OpenSubProjectReportRequest, SaveMigrationReportRequest, StoreSubProjectReportsRequest } from "./interfaces";
import { RequestType, NotificationType } from "vscode-messenger-common";

const _preFix = "migrate-integration";
Expand All @@ -30,3 +30,5 @@ export const openSubProjectReport: NotificationType<OpenSubProjectReportRequest>
export const storeSubProjectReports: NotificationType<StoreSubProjectReportsRequest> = { method: `${_preFix}/storeSubProjectReports` };
export const saveMigrationReport: NotificationType<SaveMigrationReportRequest> = { method: `${_preFix}/saveMigrationReport` };
export const migrateProject: NotificationType<MigrateRequest> = { method: `${_preFix}/migrateProject` };
export const getActiveMigrationSession: RequestType<void, ActiveMigrationSession> = { method: `${_preFix}/getActiveMigrationSession` };
export const seedMigrationHistory: RequestType<void, boolean> = { method: `${_preFix}/seedMigrationHistory` };
12 changes: 10 additions & 2 deletions workspaces/ballerina/ballerina-extension/src/RPCLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { activeAgentChanged } from '@wso2/ballerina-core';
import { ArtifactsUpdated, ArtifactNotificationHandler } from './utils/project-artifacts-handler';
import { registerMigrateIntegrationRpcHandlers } from './rpc-managers/migrate-integration/rpc-handler';
import { registerPlatformExtRpcHandlers } from './rpc-managers/platform-ext/rpc-handler';
import { MigrationPanelWebview } from './views/migration-panel/webview';

export class RPCLayer {
static _messenger: Messenger = new Messenger();
Expand All @@ -64,6 +65,9 @@ export class RPCLayer {
window.onDidChangeActiveColorTheme((theme) => {
RPCLayer._messenger.sendNotification(currentThemeChanged, { type: 'webview', webviewType: VisualizerWebview.viewType }, theme.kind);
});
} else if (isMigrationPanel(webViewPanel)) {
// Migration panel is a WebviewPanel but does not use the AI state machine.
RPCLayer._messenger.registerWebviewPanel(webViewPanel as WebviewPanel);
} else {
RPCLayer._messenger.registerWebviewView(webViewPanel as WebviewView);
AIStateMachine.service().onTransition((state) => {
Expand Down Expand Up @@ -182,6 +186,10 @@ function isWebviewPanel(webview: WebviewPanel | WebviewView): boolean {
return title === VisualizerWebview.webviewTitle;
}

function isMigrationPanel(webview: WebviewPanel | WebviewView): boolean {
return 'reveal' in webview && webview.title === "Migration Assistant";
}

export function notifyCurrentWebview() {
RPCLayer._messenger.sendNotification(projectContentUpdated, { type: 'webview', webviewType: VisualizerWebview.viewType }, true);
}
Expand All @@ -206,8 +214,8 @@ export function notifyApprovalOverlayState(state: ApprovalOverlayState) {
RPCLayer._messenger.sendNotification(approvalOverlayState, { type: 'webview', webviewType: AiPanelWebview.viewType }, state);
}

export function notifyOnIdentifierUpdated(response: ProjectStructureArtifactResponse[]) {
RPCLayer._messenger.sendNotification(onIdentifierUpdated, { type: 'webview', webviewType: VisualizerWebview.viewType }, response);
export function notifyOnIdentifierUpdated(artifacts: ProjectStructureArtifactResponse[]) {
RPCLayer._messenger.sendNotification(onIdentifierUpdated, { type: 'webview', webviewType: VisualizerWebview.viewType }, artifacts);
}

export function sendAgentChangedNotification(agentName: string) {
Expand Down
14 changes: 13 additions & 1 deletion workspaces/ballerina/ballerina-extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { activate as activateLibraryBrowser } from './features/library-browser';
import { activate as activateBIFeatures } from './features/bi';
import { activate as activateERDiagram } from './views/persist-layer-diagram';
import { activateAiPanel } from './views/ai-panel';
import { activateMigrationPanel } from './views/migration-panel';
import { debug, handleResolveMissingDependencies, log } from './utils';
import { activateUriHandlers } from './utils/uri-handlers';
import { StateMachine } from './stateMachine';
Expand All @@ -50,6 +51,7 @@ import { activate as activateNPFeatures } from './features/natural-programming/a
import { activateAgentChatPanel } from './views/agent-chat/activate';
import { activateTracing } from './features/tracing';
import { activateICP } from './features/icp';
import { onWizardChatNotify, setWizardProjectRoot, runWizardMigrationEnhancement, abortMigrationAgent, openMigratedProject } from './features/ai/migration/orchestrator';

let langClient: ExtendedLangClient;
export let isPluginStartup = true;
Expand Down Expand Up @@ -135,7 +137,14 @@ export async function activate(context: ExtensionContext) {
ballerinaExtInstance: extension.ballerinaExtInstance,
projectPath: StateMachine.context().projectPath,
VisualizerWebview,
BallerinaExtensionState
BallerinaExtensionState,
migration: {
setWizardProjectRoot,
wizardEnhancementReady: runWizardMigrationEnhancement,
abortAgent: abortMigrationAgent,
openMigratedProject,
onChatNotify: onWizardChatNotify,
},
};
}

Expand Down Expand Up @@ -202,6 +211,9 @@ export async function activateBallerina(): Promise<BallerinaExtension> {
//activate ai panel
activateAiPanel(ballerinaExtInstance);

// Activate migration enhancement panel
activateMigrationPanel(ballerinaExtInstance);

// Activate AI features
activateAIFeatures(ballerinaExtInstance);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ async function determineAffectedPackages(
* - Plan approval workflow (via ApprovalManager in TaskWrite tool)
*/
export class AgentExecutor extends AICommandExecutor<GenerateAgentCodeRequest> {
/** Tracks in-flight tool-call start times keyed by toolCallId for duration logging. */
private readonly _pendingToolCalls = new Map<string, number>();

constructor(config: AICommandConfig<GenerateAgentCodeRequest>) {
super(config);
}
Expand Down Expand Up @@ -253,6 +256,11 @@ export class AgentExecutor extends AICommandExecutor<GenerateAgentCodeRequest> {
},
];

// Resolve model and limits
const llmModel = this.config.model ?? await getAnthropicClient(ANTHROPIC_SONNET_4);
const maxSteps = this.config.agentLimits?.maxSteps ?? 50;
const maxOutputTokens = this.config.agentLimits?.maxOutputTokens ?? 8192;

Comment on lines +259 to +263

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Apply the resolved model and limit overrides to the live agent loop.

llmModel, maxSteps, and maxOutputTokens are computed here, but the stream still runs with the default model, 8192, and stepCountIs(50). Any migration execution that passes a different model or larger limits will be silently ignored during the main agent loop.

🛠️ Proposed fix
-                model,
-                maxOutputTokens: 8192,
+                model: llmModel,
+                maxOutputTokens,
@@
-                    return { messages: addCacheControlToMessages({ messages: resolvedMessages, model }) };
+                    return { messages: addCacheControlToMessages({ messages: resolvedMessages, model: llmModel }) };
@@
-                stopWhen: [stepCountIs(50), contextExhausted(compactionGuard)],
+                stopWhen: [stepCountIs(maxSteps), contextExhausted(compactionGuard)],

Also applies to: 310-325, 372-372

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-extension/src/features/ai/agent/AgentExecutor.ts`
around lines 259 - 263, The computed overrides llmModel, maxSteps, and
maxOutputTokens in AgentExecutor are never applied to the live agent loop;
update the places that instantiate or configure the streaming agent (where
default model, literal 8192, and stepCountIs(50) are currently used) to pass or
set llmModel, maxOutputTokens, and maxSteps instead. Locate the stream/agent
creation and loop configuration in AgentExecutor (the blocks around the
resolved-values assignment and the later blocks noted at the other occurrences)
and replace the hard-coded defaults with the resolved variables (llmModel,
maxOutputTokens, maxSteps) so the running agent honors the injected model and
limit overrides.

// Create tools
const tools = createToolRegistry({
eventHandler: this.config.eventHandler,
Expand All @@ -264,6 +272,7 @@ export class AgentExecutor extends AICommandExecutor<GenerateAgentCodeRequest> {
projectRootPath: this.config.executionContext.workspacePath || this.config.executionContext.projectPath || '',
generationId: this.config.generationId,
threadId: 'default',
migrationSourcePath: this.config.toolOptions?.migrationSourcePath,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid writing raw tool payloads into the debug transcript.

The new migrationSourcePath wiring enables source-reading tools, and this block forwards their raw result straight into debugLogger.logToolCall(...). workspaces/ballerina/ballerina-extension/src/features/ai/migration/debug-logger.ts:55-68 defines that argument as a short summary, not the payload, so this can now persist source code or secrets into the debug log.

🔒 Suggested fix
-                        const raw = typeof rawResult === "string"
-                            ? rawResult
-                            : rawResult === undefined
-                                ? "<no result>"
-                                : JSON.stringify(rawResult) ?? "<no result>";
-                        this.config.debugLogger.logToolCall((part as any).toolName, durationMs, raw);
+                        const resultSummary =
+                            rawResult === undefined
+                                ? "<no result>"
+                                : typeof rawResult === "string"
+                                    ? `<string:${rawResult.length} chars>`
+                                    : Array.isArray(rawResult)
+                                        ? `<array:${rawResult.length} items>`
+                                        : rawResult && typeof rawResult === "object"
+                                            ? `<object:${Object.keys(rawResult).length} keys>`
+                                            : String(rawResult);
+                        this.config.debugLogger.logToolCall((part as any).toolName, durationMs, resultSummary);

Also applies to: 569-580

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-extension/src/features/ai/agent/AgentExecutor.ts`
at line 275, The code is passing raw tool payloads (via migrationSourcePath)
into debugLogger.logToolCall which expects a short summary; remove or redact the
raw payload before calling debugLogger.logToolCall in AgentExecutor (where
migrationSourcePath and this.config.toolOptions are used) — instead send a brief
safe summary (e.g., "migration source omitted" or a sanitized summary) or omit
the field entirely; apply the same change to the other occurrence around the
block handling tool responses (the similar block at lines 569-580) so no raw
source code or secrets are written to the debug transcript.

runningServices: runningServicesManager,
webSearchEnabled: params.webSearchEnabled ?? false,
ctx: this.config.executionContext,
Expand Down Expand Up @@ -455,6 +464,14 @@ Generation stopped by user. The last in-progress task was not saved. Files have
}
);

// Notify caller with partial messages (wizard migration history persistence)
if (this.config.onMessagesAvailable) {
this.config.onMessagesAvailable(
[{ role: "user", content: streamContext.userMessageContent }, ...partialLLMMessages],
'aborted'
);
}
Comment on lines +467 to +473

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Call onMessagesAvailable on successful and error exits too.

This hook is only fired from the abort branch. If the wizard depends on it to persist migration history, completed runs and hard failures will never be saved or resumed.

🧩 Suggested follow-up
// handleStreamFinish(...)
this.config.onMessagesAvailable?.(
  [{ role: "user", content: context.userMessageContent }, ...assistantMessages],
  "completed"
);

// handleStreamError(...)
this.config.onMessagesAvailable?.(
  [{ role: "user", content: context.userMessageContent }, ...messagesToSave],
  "error"
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-extension/src/features/ai/agent/AgentExecutor.ts`
around lines 467 - 473, The onMessagesAvailable hook is only invoked in the
abort branch; update the success and error exit paths to call it as well so
migrations get persisted on completion and failures: in the stream success
handler (e.g., handleStreamFinish / wherever assistantMessages are finalized)
call this.config.onMessagesAvailable?( [{ role: "user", content:
streamContext.userMessageContent }, ...assistantMessages ], "completed" ), and
in the error handler (e.g., handleStreamError) call
this.config.onMessagesAvailable?( [{ role: "user", content:
streamContext.userMessageContent }, ...messagesToSave ], "error" ); use optional
chaining and the same message array shape as the abort branch.


// Note: Abort event is sent by base class handleExecutionError()
}

Expand Down Expand Up @@ -487,9 +504,17 @@ Generation stopped by user. The last in-progress task was not saved. Files have
throw error;
}

console.error("[AgentExecutor] Non-abort error in execute():", error);

// Abort the controller so that any in-flight tool executions
// managed by the AI SDK are cancelled and stop emitting events.
if (!this.config.abortController.signal.aborted) {
this.config.abortController.abort();
}

this.config.eventHandler({
type: "error",
content: "An error occurred during agent execution. Please check the logs for details."
content: getErrorMessage(error)
});

// For other errors, return result with error
Expand Down Expand Up @@ -535,8 +560,31 @@ Generation stopped by user. The last in-progress task was not saved. Files have
await this.handleStreamFinish(context);
break;

case "tool-call":
if (this.config.debugLogger) {
this._pendingToolCalls.set((part as any).toolCallId, Date.now());
}
break;

case "tool-result":
if (this.config.debugLogger) {
const startMs = this._pendingToolCalls.get((part as any).toolCallId);
if (startMs !== undefined) {
const durationMs = Date.now() - startMs;
const rawResult = (part as any).result;
const raw = typeof rawResult === "string"
? rawResult
: rawResult === undefined
? "<no result>"
: JSON.stringify(rawResult) ?? "<no result>";
this.config.debugLogger.logToolCall((part as any).toolName, durationMs, raw);
this._pendingToolCalls.delete((part as any).toolCallId);
}
}
break;

default:
// Tool calls/results handled automatically by SDK
// All other stream part types (step-finish, etc.) are handled by the SDK.
break;
}
}
Expand Down Expand Up @@ -682,27 +730,36 @@ Generation stopped by user. The last in-progress task was not saved. Files have
// Update chat state storage
await this.updateChatState(context, assistantMessages, tempProjectPath);

// Integrate generated code into workspace immediately so user sees changes during review
const workspaceId = context.ctx.workspacePath || context.ctx.projectPath;
const pendingReview = chatStateStorage.getPendingReviewGeneration(workspaceId, 'default');
if (pendingReview && pendingReview.reviewState.modifiedFiles.length > 0) {
const integrationCtx = { ...context.ctx };
// In workspace mode, resolve project path from modified files if not set
if (!integrationCtx.projectPath && integrationCtx.workspacePath && pendingReview.reviewState.modifiedFiles.length > 0) {
const firstBalFile = pendingReview.reviewState.modifiedFiles.find(f => f.endsWith('.bal'));
if (firstBalFile) {
const packageName = firstBalFile.split('/')[0];
if (packageName) {
integrationCtx.projectPath = path.join(integrationCtx.workspacePath, packageName);
StateMachine.context().projectPath = integrationCtx.projectPath;
// Integrate generated code into workspace immediately so user sees changes during review.
// Skip only when the temp path IS the real workspace directory (migration wizard in-place
// editing). A review-continuation run also sets existingTempPath but to a temp dir, so we
// compare resolved paths rather than just checking existingTempPath presence.
const workspaceRoot = context.ctx.workspacePath || context.ctx.projectPath;
const isInPlaceEditing =
!!workspaceRoot &&
path.resolve(tempProjectPath) === path.resolve(workspaceRoot);
if (!isInPlaceEditing) {
const workspaceId = workspaceRoot;
const pendingReview = chatStateStorage.getPendingReviewGeneration(workspaceId, 'default');
if (pendingReview && pendingReview.reviewState.modifiedFiles.length > 0) {
const integrationCtx = { ...context.ctx };
// In workspace mode, resolve project path from modified files if not set
if (!integrationCtx.projectPath && integrationCtx.workspacePath && pendingReview.reviewState.modifiedFiles.length > 0) {
const firstBalFile = pendingReview.reviewState.modifiedFiles.find(f => f.endsWith('.bal'));
if (firstBalFile) {
const packageName = firstBalFile.split('/')[0];
if (packageName) {
integrationCtx.projectPath = path.join(integrationCtx.workspacePath, packageName);
StateMachine.context().projectPath = integrationCtx.projectPath;
}
}
}
await integrateCodeToWorkspace(
pendingReview.reviewState.tempProjectPath!,
new Set(pendingReview.reviewState.modifiedFiles),
integrationCtx
);
}
await integrateCodeToWorkspace(
pendingReview.reviewState.tempProjectPath!,
new Set(pendingReview.reviewState.modifiedFiles),
integrationCtx
);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// Emit UI events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ import { createConnectorGeneratorTool, CONNECTOR_GENERATOR_TOOL } from './tools/
import { LIBRARY_SEARCH_TOOL, getLibrarySearchTool } from './tools/library-search';
import { createConfigCollectorTool, CONFIG_COLLECTOR_TOOL } from './tools/config-collector';
import { createTestRunnerTool, TEST_RUNNER_TOOL_NAME } from './tools/test-runner';
import {
createMigrationSourceListTool,
createMigrationSourceReadTool,
MIGRATION_SOURCE_LIST_TOOL,
MIGRATION_SOURCE_READ_TOOL,
} from './tools/migration-source-reader';
import { createBallerinaRunTool, BALLERINA_RUN_TOOL_NAME } from './tools/ballerina-run';
import { createBallerinaGetLogsTool, BALLERINA_GET_LOGS_TOOL_NAME } from './tools/ballerina-get-logs';
import { createBallerinaStopTool, BALLERINA_STOP_TOOL_NAME } from './tools/ballerina-stop';
Expand All @@ -60,13 +66,15 @@ export interface ToolRegistryOptions {
projectRootPath: string;
generationId: string;
threadId?: string;
/** Absolute path to the original migration source project (Mule, Tibco, etc.). */
migrationSourcePath?: string;
runningServices: RunningServicesManager;
webSearchEnabled: boolean;
ctx: ExecutionContext;
}

export function createToolRegistry(opts: ToolRegistryOptions) {
const { eventHandler, tempProjectPath, modifiedFiles, allModifiedFiles, projects, generationType, projectRootPath, generationId, threadId, webSearchEnabled, ctx } = opts;
const { eventHandler, tempProjectPath, modifiedFiles, allModifiedFiles, projects, generationType, projectRootPath, generationId, threadId, migrationSourcePath, webSearchEnabled, ctx } = opts;
return {
[TASK_WRITE_TOOL_NAME]: createTaskWriteTool(
eventHandler,
Expand Down Expand Up @@ -114,6 +122,11 @@ export function createToolRegistry(opts: ToolRegistryOptions) {
),
[DIAGNOSTICS_TOOL_NAME]: createDiagnosticsTool(tempProjectPath, eventHandler),
[TEST_RUNNER_TOOL_NAME]: createTestRunnerTool(tempProjectPath, eventHandler, modifiedFiles, allModifiedFiles, ctx),
// Migration source tools — registered only when a source project path is available
...(migrationSourcePath ? {
[MIGRATION_SOURCE_LIST_TOOL]: createMigrationSourceListTool(eventHandler, migrationSourcePath),
[MIGRATION_SOURCE_READ_TOOL]: createMigrationSourceReadTool(eventHandler, migrationSourcePath),
} : {}),
[HURL_TOOL_NAME]: createHurlTool(eventHandler),
[BALLERINA_RUN_TOOL_NAME]: createBallerinaRunTool(tempProjectPath, opts.runningServices, eventHandler, modifiedFiles, allModifiedFiles, ctx),
[BALLERINA_GET_LOGS_TOOL_NAME]: createBallerinaGetLogsTool(opts.runningServices, eventHandler),
Expand Down
Loading
Loading