-
Notifications
You must be signed in to change notification settings - Fork 196
feat: agent swarm #424
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
base: main
Are you sure you want to change the base?
feat: agent swarm #424
Changes from all commits
27dded5
d711cf0
45a74b1
1cd720a
6f89819
9e58f5c
d3f92ef
8bc6b5f
329238b
0c7d35f
9db2cd2
4d76bf0
c1b5ba7
4797e90
0a93675
c0bfa73
5729fbc
42ff90b
a116227
68ec665
f5841ae
ce6a471
99adec6
b418a04
765f108
75e00b8
b922dbe
108f635
263c968
206183e
65454eb
ef7521a
a952c70
96a081a
ef4a584
95936ff
61c3a03
7122b52
e175ddf
71d85df
43c708f
fe4aa16
dbc99be
2c471c8
e7a07aa
d72e279
82d3831
615256d
bc82e59
2f965c0
3e79efa
0991872
fa64e52
a0cd20c
e8f24eb
896dfde
d529b75
5cf861b
dc029d5
6e87a7b
536d27c
f52f253
29de45b
06d452f
b9dc203
4a2eede
42b1fb9
548ada8
0d50b54
7c9e5dd
1dc2a84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| "@moonshot-ai/agent-core": minor | ||
| "@moonshot-ai/kimi-code-sdk": minor | ||
| "@moonshot-ai/kimi-code": minor | ||
| --- | ||
|
|
||
| Add template-based AgentSwarm launches with live TUI progress. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| import type { PermissionMode } from '@moonshot-ai/kimi-code-sdk'; | ||
|
|
||
| import { | ||
| SwarmStartPermissionPromptComponent, | ||
| type SwarmStartPermissionChoice, | ||
| } from '../components/dialogs/swarm-start-permission-prompt'; | ||
| import { | ||
| SwarmModeMarkerComponent, | ||
| type SwarmModeMarkerState, | ||
| } from '../components/messages/swarm-markers'; | ||
| import { LLM_NOT_SET_MESSAGE, NO_ACTIVE_SESSION_MESSAGE } from '../constant/kimi-tui'; | ||
| import { formatErrorMessage } from '../utils/event-payload'; | ||
| import type { SlashCommandHost } from './dispatch'; | ||
|
|
||
| export async function handleSwarmCommand(host: SlashCommandHost, args: string): Promise<void> { | ||
| if (host.session === undefined) { | ||
| host.showError(NO_ACTIVE_SESSION_MESSAGE); | ||
| return; | ||
| } | ||
|
|
||
| const prompt = args.trim(); | ||
| const mode = swarmModeSubcommand(prompt); | ||
| if (mode !== undefined) { | ||
| await applySwarmMode(host, mode); | ||
| return; | ||
| } | ||
|
|
||
| if (prompt.length === 0) { | ||
| await applySwarmMode(host, !host.state.appState.swarmMode); | ||
| return; | ||
| } | ||
|
|
||
| if (host.state.appState.model.trim().length === 0) { | ||
| host.showError(LLM_NOT_SET_MESSAGE); | ||
| return; | ||
| } | ||
|
|
||
| if (host.state.appState.permissionMode === 'manual') { | ||
| showSwarmStartPermissionPrompt(host, prompt); | ||
|
Comment on lines
+38
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In Manual mode, Useful? React with 👍 / 👎. |
||
| return; | ||
| } | ||
|
|
||
| await startSwarmTask(host, prompt); | ||
| } | ||
|
|
||
| function showSwarmStartPermissionPrompt(host: SlashCommandHost, prompt: string): void { | ||
| const commandText = `/swarm ${prompt}`; | ||
| const cancelStart = (): void => { | ||
| host.restoreInputText(commandText); | ||
| host.showStatus('Swarm task not started.'); | ||
| }; | ||
| host.mountEditorReplacement( | ||
| new SwarmStartPermissionPromptComponent({ | ||
| colors: host.state.theme.colors, | ||
| onSelect: (choice) => { | ||
| host.restoreEditor(); | ||
| void startSwarmWithPermission(host, prompt, choice); | ||
| }, | ||
| onCancel: cancelStart, | ||
| }), | ||
| ); | ||
| } | ||
|
|
||
| async function startSwarmWithPermission( | ||
| host: SlashCommandHost, | ||
| prompt: string, | ||
| choice: SwarmStartPermissionChoice, | ||
| ): Promise<void> { | ||
| if (choice === 'auto') { | ||
| if (!(await setPermissionForSwarm(host, choice))) return; | ||
| } | ||
| await startSwarmTask(host, prompt); | ||
| } | ||
|
|
||
| async function setPermissionForSwarm(host: SlashCommandHost, mode: PermissionMode): Promise<boolean> { | ||
| try { | ||
| await host.requireSession().setPermission(mode); | ||
| } catch (error) { | ||
| host.showError(`Failed to set permission mode: ${formatErrorMessage(error)}`); | ||
| return false; | ||
| } | ||
| host.setAppState({ permissionMode: mode }); | ||
| return true; | ||
| } | ||
|
|
||
| async function startSwarmTask(host: SlashCommandHost, prompt: string): Promise<void> { | ||
| if (!host.state.appState.swarmMode && !(await setSwarmMode(host, true, 'task'))) { | ||
| return; | ||
| } | ||
| renderSwarmModeMarker(host, 'active'); | ||
| host.sendNormalUserInput(prompt); | ||
| } | ||
|
|
||
| async function applySwarmMode(host: SlashCommandHost, enabled: boolean): Promise<void> { | ||
| if (enabled && host.state.appState.swarmMode) { | ||
| host.showStatus('Swarm mode is already on.'); | ||
| return; | ||
| } | ||
| if (!enabled && !host.state.appState.swarmMode) { | ||
| host.showStatus('Swarm mode is already off.'); | ||
| return; | ||
| } | ||
| if (!(await setSwarmMode(host, enabled, 'manual'))) return; | ||
| renderSwarmModeMarker(host, enabled ? 'active' : 'inactive'); | ||
| } | ||
|
|
||
| async function setSwarmMode( | ||
| host: SlashCommandHost, | ||
| enabled: boolean, | ||
| trigger: 'manual' | 'task', | ||
| ): Promise<boolean> { | ||
| try { | ||
| await host.requireSession().setSwarmMode(enabled, trigger); | ||
| } catch (error) { | ||
| host.showError( | ||
| `Failed to ${enabled ? 'enable' : 'disable'} swarm mode: ${formatErrorMessage(error)}`, | ||
| ); | ||
| return false; | ||
| } | ||
| host.setAppState({ swarmMode: enabled }); | ||
| host.state.swarmModeEntry = enabled ? trigger : undefined; | ||
| return true; | ||
| } | ||
|
|
||
| function swarmModeSubcommand(input: string): boolean | undefined { | ||
| const command = input.toLowerCase(); | ||
| if (command === 'on') return true; | ||
| if (command === 'off') return false; | ||
| return undefined; | ||
| } | ||
|
|
||
| function renderSwarmModeMarker(host: SlashCommandHost, state: SwarmModeMarkerState): void { | ||
| host.state.transcriptContainer.addChild( | ||
| new SwarmModeMarkerComponent(state, host.state.theme.colors), | ||
| ); | ||
| host.state.ui.requestRender(); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.