-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(workflow): add pause and resume functionality to team workflow #180
Open
anthonydevs17
wants to merge
17
commits into
kaiban-ai:main
Choose a base branch
from
anthonydevs17:pause-and-resume-agents-workflow
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+12,077
−464
Open
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
64f815e
feat(workflow): add pause and resume functionality to team workflow
anthonydevs17 9662c83
remove logs
anthonydevs17 1ca477c
feat(agent): add pause handling to ReactChampionAgent workflow
anthonydevs17 94c5e78
feat(workflow): implement stop functionality for team workflow
anthonydevs17 ac46726
feat(workflow): enhance workflow control with pause, resume, and stop…
anthonydevs17 c30a39d
Merge branch 'main' of https://github.com/kaiban-ai/KaibanJS into pau…
anthonydevs17 5ca097f
fix(tools): update README formatting for better readability
anthonydevs17 ea3f631
Merge branch 'main' of https://github.com/kaiban-ai/KaibanJS into pau…
anthonydevs17 5b15c1f
feat(workflow): streamline workflow management with enhanced pause, r…
anthonydevs17 ce70eb3
feat(tests): update snapshots to include currentIterations and lastFe…
anthonydevs17 d4a7e7f
docs: remove redundant newline in README.md
anthonydevs17 b10e551
refactor(reactChampionAgent): remove redundant pause check in handleL…
anthonydevs17 ca0b70a
feat(workflow): implement task pause functionality and enhance agent …
anthonydevs17 49b6101
feat(subscriber): add PAUSED state to task status updates
anthonydevs17 ef4a6a0
feat(workflow): enhance agent state management and task queue handling
anthonydevs17 b6fc578
feat(tests): update snapshots with detailed lastFeedbackMessage for v…
anthonydevs17 db13940
feat(agent): add workOnTaskResume method and integrate into workflow …
anthonydevs17 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
feat(workflow): streamline workflow management with enhanced pause, r…
…esume, and stop methods - Refactored Team class methods (pause, resume, stop) to utilize new workflow management functions directly from the store, improving code clarity and reducing redundancy. - Updated ReactChampionAgent to track the last feedback message and handle task execution more effectively, including abort handling. - Introduced new error classes (StopAbortError, PauseAbortError) for better error management during workflow interruptions. - Enhanced task logging for aborted tasks, capturing relevant statistics and error details for improved debugging. - Integrated workflow action enums to standardize workflow control actions across the application.
commit 5b15c1ff72dfdb2a0debd4b944743bc30575bdcc
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
import { ChatMessageHistory } from 'langchain/stores/message/in_memory'; | ||
import { | ||
WORKFLOW_STATUS_enum, | ||
TASK_STATUS_enum, | ||
WORKFLOW_ACTION_enum, | ||
} from '../utils/enums'; | ||
import { | ||
StopAbortError, | ||
PauseAbortError, | ||
WorkflowError, | ||
} from '../utils/errors'; | ||
import { logger } from '../utils/logger'; | ||
import PQueue from 'p-queue'; | ||
|
||
export const useWorkflowLoopStore = (set, get) => ({ | ||
taskQueue: new PQueue({ concurrency: 1 }), | ||
activePromises: new Map(), | ||
clearAgentLoopState: (agentId) => | ||
set((store) => { | ||
const newAgents = [...store.agents]; | ||
newAgents.forEach(({ agentInstance }) => { | ||
if (agentInstance.id === agentId) { | ||
agentInstance.interactionsHistory = new ChatMessageHistory(); | ||
agentInstance.lastFeedbackMessage = null; | ||
agentInstance.currentIterations = 0; | ||
} | ||
}); | ||
logger.info('cleared agent loop state', agentId); | ||
return { agents: newAgents }; | ||
}), | ||
|
||
// Initialize | ||
initializeWorkflow: () => { | ||
set((state) => ({ | ||
...state, | ||
teamWorkflowStatus: WORKFLOW_STATUS_enum.RUNNING, | ||
taskQueue: new PQueue({ concurrency: 1 }), | ||
})); | ||
}, | ||
|
||
// Promise Management | ||
trackPromise: (agentId, promiseObj) => { | ||
set((state) => { | ||
const agentPromises = state.activePromises.get(agentId) || new Set(); | ||
agentPromises.add(promiseObj); | ||
return { | ||
activePromises: new Map(state.activePromises).set( | ||
agentId, | ||
agentPromises | ||
), | ||
}; | ||
}); | ||
}, | ||
|
||
removePromise: (agentId, promiseObj) => { | ||
set((state) => { | ||
const agentPromises = state.activePromises.get(agentId); | ||
if (agentPromises) { | ||
agentPromises.delete(promiseObj); | ||
} | ||
return { | ||
activePromises: new Map(state.activePromises), | ||
}; | ||
}); | ||
}, | ||
|
||
abortAgentPromises: (agentId, action) => { | ||
const agentPromises = get().activePromises.get(agentId); | ||
if (agentPromises) { | ||
for (const { reject } of agentPromises) { | ||
switch (action) { | ||
case WORKFLOW_ACTION_enum.STOP: | ||
reject(new StopAbortError()); | ||
break; | ||
case WORKFLOW_ACTION_enum.PAUSE: | ||
reject(new PauseAbortError()); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
set((state) => ({ | ||
activePromises: new Map(state.activePromises).set(agentId, new Set()), | ||
})); | ||
} | ||
}, | ||
|
||
// Workflow Control Actions | ||
pauseWorkflow: async () => { | ||
const currentStatus = get().teamWorkflowStatus; | ||
if (currentStatus !== WORKFLOW_STATUS_enum.RUNNING) { | ||
throw new WorkflowError('Cannot pause workflow unless it is running'); | ||
} | ||
|
||
// Pause task queue | ||
get().taskQueue.pause(); | ||
// Abort all active agent promises | ||
for (const agentId of get().activePromises.keys()) { | ||
get().abortAgentPromises(agentId, WORKFLOW_ACTION_enum.PAUSE); | ||
} | ||
|
||
set({ teamWorkflowStatus: WORKFLOW_STATUS_enum.PAUSED }); | ||
logger.info('Workflow paused'); | ||
console.log(get().agents); | ||
}, | ||
|
||
resumeWorkflow: async () => { | ||
const currentStatus = get().teamWorkflowStatus; | ||
if (currentStatus !== WORKFLOW_STATUS_enum.PAUSED) { | ||
throw new WorkflowError('Cannot resume workflow unless it is paused'); | ||
} | ||
set({ | ||
teamWorkflowStatus: WORKFLOW_STATUS_enum.RESUMED, | ||
}); | ||
const tasks = get().tasks; | ||
|
||
tasks.forEach((task) => { | ||
if (task.status === TASK_STATUS_enum.BLOCKED) { | ||
get().updateTaskStatus(task.id, TASK_STATUS_enum.DOING); | ||
} | ||
}); | ||
|
||
// Resume task queue | ||
get().taskQueue.start(); | ||
|
||
logger.info('Workflow resumed'); | ||
set({ teamWorkflowStatus: WORKFLOW_STATUS_enum.RUNNING }); | ||
}, | ||
|
||
stopWorkflow: async () => { | ||
const currentStatus = get().teamWorkflowStatus; | ||
|
||
if ( | ||
currentStatus !== WORKFLOW_STATUS_enum.RUNNING && | ||
currentStatus !== WORKFLOW_STATUS_enum.PAUSED | ||
) { | ||
throw new WorkflowError( | ||
'Cannot stop workflow unless it is running or paused' | ||
); | ||
} | ||
|
||
set({ teamWorkflowStatus: WORKFLOW_STATUS_enum.STOPPING }); | ||
|
||
try { | ||
// Abort all active agent promises | ||
for (const agentId of get().activePromises.keys()) { | ||
get().abortAgentPromises(agentId, WORKFLOW_ACTION_enum.STOP); | ||
get().clearAgentLoopState(agentId); | ||
} | ||
|
||
// Clear task queue | ||
get().taskQueue.clear(); | ||
|
||
// Update all DOING tasks to TODO | ||
const tasks = get().tasks; | ||
tasks.forEach((task) => { | ||
get().updateTaskStatus(task.id, TASK_STATUS_enum.TODO); | ||
}); | ||
|
||
set({ teamWorkflowStatus: WORKFLOW_STATUS_enum.STOPPED }); | ||
logger.info('Workflow stopped successfully'); | ||
} catch (error) { | ||
logger.error('Error stopping workflow:', error); | ||
set({ teamWorkflowStatus: WORKFLOW_STATUS_enum.STOPPED }); | ||
throw error; | ||
} | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Blocked tasks are being reset here to the Doing state?