Skip to content

Commit f34dbd4

Browse files
libing0526libing0526
andauthored
feat(cli): add chat command for accessing interface (#8)
* docs: update name of latest installer exe in download section * fix(env): add CUDA path and fix quote escaping * fix(env): add cuda path and fix quote escaping * feat(cli): add chat command for accessing interface --------- Co-authored-by: libing0526 <libqtweb@gmail.com>
1 parent 60e3f03 commit f34dbd4

File tree

4 files changed

+136
-1
lines changed

4 files changed

+136
-1
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Parallax Windows CLI adopts modern C++ design patterns and mainly contains the f
4444
- Unified command parsing and execution framework
4545
- Command base class based on template method pattern
4646
- Support for standardized parameter validation, environment preparation, and execution flow
47-
- **Supported Commands**: check, install, config, run, join, cmd
47+
- **Supported Commands**: check, install, config, run, join, chat, cmd
4848

4949
### 2. Environment Installer
5050
- **Location**: `src/parallax/environment/`
@@ -133,6 +133,9 @@ parallax check
133133
134134
# Start Parallax inference server (optional)
135135
parallax run
136+
137+
# Access chat interface (optional)
138+
parallax chat
136139
```
137140

138141
## Command Reference
@@ -180,6 +183,12 @@ Join distributed inference cluster as a node
180183
parallax join [args...]
181184
```
182185

186+
### `parallax chat`
187+
Access chat interface from non-scheduler computer
188+
```cmd
189+
parallax chat [args...]
190+
```
191+
183192
### `parallax cmd`
184193
Execute commands in WSL or Python virtual environment
185194
```cmd
@@ -189,6 +198,7 @@ parallax cmd [--venv] <command> [args...]
189198
**Command Descriptions**:
190199
- `run`: Start Parallax inference server directly in WSL. You can pass any arguments supported by `parallax run` command. Examples: `parallax run -m Qwen/Qwen3-0.6B`, `parallax run --port 8080`
191200
- `join`: Join distributed inference cluster as a worker node. You can pass any arguments supported by `parallax join` command. Examples: `parallax join -m Qwen/Qwen3-0.6B`, `parallax join -s scheduler-addr`
201+
- `chat`: Access chat interface from any non-scheduler computer. You can pass any arguments supported by `parallax chat` command. Examples: `parallax chat` (local network), `parallax chat -s scheduler-addr` (public network), `parallax chat --host 0.0.0.0` (allow external access). After launching, visit http://localhost:3002 in your browser.
192202
- `cmd`: Pass-through commands to WSL environment, supports `--venv` option to run in parallax project's Python virtual environment
193203

194204
**Main Configuration Items**:
@@ -291,6 +301,9 @@ parallax config list
291301
# Start inference server test
292302
parallax run
293303
304+
# Access chat interface test
305+
parallax chat
306+
294307
# Execute commands in WSL
295308
parallax cmd "python --version"
296309

src/parallax/cli/command_parser.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ void CommandParser::InitializeBuiltinCommands() {
158158
return static_cast<int>(result);
159159
});
160160

161+
// Register chat command (access chat interface from non-scheduler computer)
162+
RegisterCommand("chat", "Access chat interface from non-scheduler computer",
163+
[](const std::vector<std::string>& args) -> int {
164+
parallax::commands::ModelChatCommand chat_cmd;
165+
auto result = chat_cmd.Execute(args);
166+
return static_cast<int>(result);
167+
});
168+
161169
// Register cmd command (pass-through command to WSL or virtual environment)
162170
RegisterCommand("cmd",
163171
"Execute commands in WSL or Python virtual environment",

src/parallax/cli/commands/model_commands.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,5 +165,96 @@ std::string ModelJoinCommand::BuildJoinCommand(const CommandContext& context) {
165165
return command_stream.str();
166166
}
167167

168+
// ModelChatCommand implementation
169+
CommandResult ModelChatCommand::ValidateArgsImpl(CommandContext& context) {
170+
// Check if it's a help request
171+
if (context.args.size() == 1 &&
172+
(context.args[0] == "--help" || context.args[0] == "-h")) {
173+
ShowHelpImpl();
174+
return CommandResult::Success;
175+
}
176+
177+
// chat command can be executed without parameters (using default settings)
178+
return CommandResult::Success;
179+
}
180+
181+
CommandResult ModelChatCommand::ExecuteImpl(const CommandContext& context) {
182+
// Build chat command: parallax chat [user parameters...]
183+
std::string chat_command = BuildChatCommand(context);
184+
185+
// Build complete WSL command with venv activation and CUDA environment
186+
std::string full_command = BuildVenvActivationCommand(context);
187+
188+
// If proxy is configured, add proxy environment variables
189+
if (!context.proxy_url.empty()) {
190+
full_command += " && HTTP_PROXY='" + context.proxy_url +
191+
"' HTTPS_PROXY='" + context.proxy_url + "' " +
192+
chat_command;
193+
} else {
194+
full_command += " && " + chat_command;
195+
}
196+
197+
std::string wsl_command = BuildWSLCommand(context, full_command);
198+
199+
info_log("Executing chat interface command: %s", wsl_command.c_str());
200+
201+
// Use WSLProcess to execute command for real-time output
202+
WSLProcess wsl_process;
203+
int exit_code = wsl_process.Execute(wsl_command);
204+
205+
if (exit_code == 0) {
206+
ShowInfo("Chat interface started successfully. Visit http://localhost:3002 in your browser.");
207+
return CommandResult::Success;
208+
} else {
209+
ShowError("Failed to start chat interface with exit code: " +
210+
std::to_string(exit_code));
211+
return CommandResult::ExecutionError;
212+
}
213+
}
214+
215+
void ModelChatCommand::ShowHelpImpl() {
216+
std::cout << "Usage: parallax chat [args...]\n\n";
217+
std::cout << "Access the chat interface from any non-scheduler computer.\n\n";
218+
std::cout << "This command will:\n";
219+
std::cout << " 1. Change to ~/parallax directory\n";
220+
std::cout << " 2. Activate the Python virtual environment\n";
221+
std::cout << " 3. Set proxy environment variables (if configured)\n";
222+
std::cout << " 4. Execute 'parallax chat' with your arguments\n";
223+
std::cout << " 5. Start chat server at http://localhost:3002\n\n";
224+
std::cout << "Arguments:\n";
225+
std::cout << " args... Arguments to pass to parallax chat "
226+
"(optional)\n\n";
227+
std::cout << "Options:\n";
228+
std::cout << " --help, -h Show this help message\n\n";
229+
std::cout << "Examples:\n";
230+
std::cout
231+
<< " parallax chat # Execute: parallax "
232+
"chat (local area network)\n";
233+
std::cout << " parallax chat -s scheduler-addr # Execute: parallax "
234+
"chat -s scheduler-addr (public network)\n";
235+
std::cout
236+
<< " parallax chat -s 12D3KooWLX7MWuzi1Txa5LyZS4eTQ2tPaJijheH8faHggB9SxnBu\n";
237+
std::cout << " # Connect to specific scheduler\n";
238+
std::cout << " parallax chat --host 0.0.0.0 # Allow API access from other machines\n\n";
239+
std::cout << "Note: All arguments will be passed to the built-in "
240+
"parallax chat script\n";
241+
std::cout << " in the Parallax Python virtual environment.\n";
242+
std::cout << " After launching, visit http://localhost:3002 in your browser.\n";
243+
}
244+
245+
std::string ModelChatCommand::BuildChatCommand(const CommandContext& context) {
246+
std::ostringstream command_stream;
247+
248+
// Built-in execution of parallax chat
249+
command_stream << "parallax chat";
250+
251+
// If there are user parameters, append them
252+
for (const auto& arg : context.args) {
253+
command_stream << " " << EscapeForShell(arg);
254+
}
255+
256+
return command_stream.str();
257+
}
258+
168259
} // namespace commands
169260
} // namespace parallax

src/parallax/cli/commands/model_commands.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,28 @@ class ModelJoinCommand : public WSLCommand<ModelJoinCommand> {
126126
std::string BuildJoinCommand(const CommandContext& context);
127127
};
128128

129+
// Chat command - access chat interface from non-scheduler computer
130+
class ModelChatCommand : public WSLCommand<ModelChatCommand> {
131+
public:
132+
std::string GetName() const override { return "chat"; }
133+
std::string GetDescription() const override {
134+
return "Access chat interface from non-scheduler computer";
135+
}
136+
137+
EnvironmentRequirements GetEnvironmentRequirements() {
138+
EnvironmentRequirements req;
139+
req.need_wsl = true;
140+
req.sync_proxy = true;
141+
return req;
142+
}
143+
144+
CommandResult ValidateArgsImpl(CommandContext& context);
145+
CommandResult ExecuteImpl(const CommandContext& context);
146+
void ShowHelpImpl();
147+
148+
private:
149+
std::string BuildChatCommand(const CommandContext& context);
150+
};
151+
129152
} // namespace commands
130153
} // namespace parallax

0 commit comments

Comments
 (0)