Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion workspaces/agent-forge/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion workspaces/agent-forge/plugins/agent-forge/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@caipe/plugin-agent-forge",
"version": "0.3.45",
"version": "0.3.46",
"main": "src/index.ts",
"types": "src/index.ts",
"exports": {
Expand Down
18 changes: 9 additions & 9 deletions workspaces/agent-forge/plugins/agent-forge/src/a2a/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,9 @@ export interface Message {
parts: Part[];
metadata?: { [key: string]: any };
reference_task_ids?: string[];
message_id: string;
task_id?: string;
context_id?: string;
messageId: string;
taskId?: string;
contextId?: string;
kind: 'message';
}

Expand All @@ -241,7 +241,7 @@ export interface TaskStatus {

export interface Task {
id: string;
context_id: string;
contextId: string;
status: TaskStatus;
history?: Message[];
artifacts?: Artifact[];
Expand All @@ -250,21 +250,21 @@ export interface Task {
}

export interface TaskStatusUpdateEvent {
task_id: string;
context_id: string;
taskId: string;
contextId: string;
kind: 'status-update';
status: TaskStatus;
final: boolean;
metadata?: { [key: string]: any };
}

export interface TaskArtifactUpdateEvent {
task_id: string;
context_id: string;
taskId: string;
contextId: string;
kind: 'artifact-update';
artifact: Artifact;
append?: boolean;
last_chunk?: boolean;
lastChunk?: boolean;
metadata?: { [key: string]: any };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,14 @@ export class ChatbotApi {

// Use session contextId if provided, otherwise use internal contextId
const contextToUse = sessionContextId || this.contextId;

console.log('🔍 CONTEXT DEBUG:', {
sessionContextId,
internalContextId: this.contextId,
contextToUse,
newContext,
});

if (!newContext && contextToUse !== undefined) {
sendParams.message.contextId = contextToUse;
}
Expand All @@ -510,7 +518,7 @@ export class ChatbotApi {

const task: Task = taskResult?.result as Task;

this.contextId = task.context_id;
this.contextId = task.contextId;

// Return the full task response instead of just the text
return task;
Expand Down Expand Up @@ -566,8 +574,20 @@ export class ChatbotApi {
token,
)) {
// Update internal contextId from streamed events
if (event.kind === 'task' && event.contextId) {
this.contextId = event.contextId;
// Also check if context_id is returned (snake_case) and normalize to camelCase
const contextId =
(event as any).contextId || (event as any).context_id;
if (contextId) {
console.log('🔍 CONTEXT ID:', contextId);
// Ensure standard camelCase property exists for downstream consumers
if (!(event as any).contextId) {
(event as any).contextId = contextId;
}
if (event.kind === 'task') {
this.contextId = contextId;
}
} else {
console.log('🔍 NO CONTEXT ID');
}
yield event;
}
Expand Down Expand Up @@ -631,7 +651,10 @@ export class ChatbotApi {
const err = error as AxiosError;
if (err?.isAxiosError) {
throw new Error(
`Error submitting feedback: ${[err.message, err.cause?.message]
`Error submitting feedback: ${[
err.message,
(err.cause as any)?.message,
]
.filter(Boolean)
.join(' - ')}`,
);
Expand All @@ -646,7 +669,7 @@ export class ChatbotApi {
throw new Error('A2A client not initialized');
}
const token = await this.getToken();
await this.client.cancelTask({ taskId }, token);
await this.client.cancelTask({ id: taskId }, token);
console.log('✅ A2A cancellation sent for task:', taskId);
} catch (error) {
console.error('❌ Failed to send A2A cancellation:', error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ export function AgentForgePage() {
useState(false);
const lastScrollPositionRef = useRef<number>(-1);
const buttonToggleTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const lastCollapseTimeRef = useRef<number>(0);
// const lastCollapseTimeRef = useRef<number>(0);
const gracefulScrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);
// Reference to input field for focus management
const inputRef = useRef<HTMLInputElement>(null);
Expand Down Expand Up @@ -1379,7 +1379,7 @@ export function AgentForgePage() {

setIsManualLoadingInProgress(true);
setLoadedMessageCount(newCount);
setShowLoadMoreButton(false);
// setShowLoadMoreButton(false); // Keep button visible for sequential loading

// Clear manual loading flag after a short delay
setTimeout(() => {
Expand All @@ -1400,13 +1400,8 @@ export function AgentForgePage() {
}
lastScrollPositionRef.current = scrollTop;

const isAtTop = scrollTop < 50; // Within 50px of top
const isAtBottom = scrollTop + clientHeight >= scrollHeight - 100; // Within 100px of bottom

// Show load more button when user scrolls up and there are more messages to load
const totalMessages = currentSession?.messages?.length || 0;
const hasMoreMessages = loadedMessageCount < totalMessages;

// Debounced button state changes to prevent flickering
const debouncedButtonToggle = (shouldShow: boolean, reason: string) => {
if (buttonToggleTimeoutRef.current) {
Expand All @@ -1424,65 +1419,11 @@ export function AgentForgePage() {
}, 50); // Small debounce delay
};

// Don't auto-show button on scroll to prevent issues when switching sessions
// Users can manually scroll to trigger load if needed

// Performance optimization: Auto-collapse to default count when user scrolls to bottom
// This prevents DOM bloat with large message histories
if (
isAtBottom &&
loadedMessageCount > DEFAULT_MESSAGE_COUNT &&
!isManualLoadingInProgress
) {
// Throttle auto-collapse to prevent rapid cycles (minimum 3 seconds between collapses)
const currentTime = Date.now();
const timeSinceLastCollapse = currentTime - lastCollapseTimeRef.current;

if (timeSinceLastCollapse > 3000) {
console.log(
'🔽 Auto-collapse for performance:',
loadedMessageCount,
'→',
DEFAULT_MESSAGE_COUNT,
);
lastCollapseTimeRef.current = currentTime;

// Capture that user was at bottom BEFORE we change DOM
const userWasAtBottom = isAtBottom;

setLoadedMessageCount(DEFAULT_MESSAGE_COUNT);
setShowLoadMoreButton(false); // Hide button since we're back to default count

// Gracefully scroll to bottom after DOM height changes to prevent jarring jumps
if (userWasAtBottom) {
// Clear any existing graceful scroll timeout
if (gracefulScrollTimeoutRef.current) {
clearTimeout(gracefulScrollTimeoutRef.current);
}

gracefulScrollTimeoutRef.current = setTimeout(() => {
const container = document.querySelector(
'[data-testid="messages-container"]',
) as HTMLElement;
if (container) {
console.log(
'📍 Graceful scroll to bottom after auto-collapse (preventing jarring jump)',
);
container.scrollTo({
top: container.scrollHeight,
behavior: 'smooth',
});
}
gracefulScrollTimeoutRef.current = null;
}, 100); // Small delay to let DOM update after message count change
}
} else {
console.log(
'🔽 Auto-collapse throttled - only',
Math.round(timeSinceLastCollapse / 1000),
'seconds since last collapse',
);
}
// Show button when user scrolls up
if (!isAtBottom) {
debouncedButtonToggle(true, 'User scrolled up - showing button');
} else {
debouncedButtonToggle(false, 'User at bottom - hiding button');
}
},
[
Expand All @@ -1505,26 +1446,10 @@ export function AgentForgePage() {
};
}, []);

// Initialize load more button visibility on mount/session change - don't show initially
// Reset load more button visibility when switching sessions
useEffect(() => {
if (!autoScrollEnabled && currentSession?.messages) {
// Don't show button on initial load, only after user scrolls up
const shouldShowButton = false;

if (shouldShowButton !== showLoadMoreButton) {
console.log(
'📜 Initializing Load Earlier Messages button visibility (hidden on first load):',
shouldShowButton,
);
setShowLoadMoreButton(shouldShowButton);
}
}
}, [
currentSession?.messages?.length,
loadedMessageCount,
isManualLoadingInProgress,
autoScrollEnabled,
]);
setShowLoadMoreButton(false);
}, [currentSessionId]);

// Load chat history from localStorage on mount (replace initial session if stored data exists)
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion workspaces/agent-forge/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,7 @@
integrity sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==

"@caipe/plugin-agent-forge@file:/home/suwhang/Outshift/cnoe-io/community-plugins/workspaces/agent-forge/plugins/agent-forge":
version "0.3.45"
version "0.3.46"
resolved "file:plugins/agent-forge"
dependencies:
"@agentic-profile/a2a-client" "^0.6.2"
Expand Down
Loading