|
3 | 3 |
|
4 | 4 | #include <copilot/client.hpp> |
5 | 5 | #include <copilot/session.hpp> |
| 6 | +#include <condition_variable> |
6 | 7 |
|
7 | 8 | namespace copilot |
8 | 9 | { |
@@ -83,6 +84,68 @@ std::future<std::vector<SessionEvent>> Session::get_messages() |
83 | 84 | ); |
84 | 85 | } |
85 | 86 |
|
| 87 | +std::future<std::optional<SessionEvent>> Session::send_and_wait( |
| 88 | + MessageOptions options, |
| 89 | + std::chrono::seconds timeout) |
| 90 | +{ |
| 91 | + return std::async( |
| 92 | + std::launch::async, |
| 93 | + [this, options = std::move(options), timeout]() -> std::optional<SessionEvent> |
| 94 | + { |
| 95 | + std::mutex mtx; |
| 96 | + std::condition_variable cv; |
| 97 | + bool done = false; |
| 98 | + std::optional<SessionEvent> last_assistant_message; |
| 99 | + std::optional<std::string> error_message; |
| 100 | + |
| 101 | + // Subscribe to events |
| 102 | + auto subscription = on( |
| 103 | + [&](const SessionEvent& evt) |
| 104 | + { |
| 105 | + std::lock_guard<std::mutex> lock(mtx); |
| 106 | + if (evt.type == SessionEventType::AssistantMessage) |
| 107 | + { |
| 108 | + last_assistant_message = evt; |
| 109 | + } |
| 110 | + else if (evt.type == SessionEventType::SessionIdle) |
| 111 | + { |
| 112 | + done = true; |
| 113 | + cv.notify_one(); |
| 114 | + } |
| 115 | + else if (evt.type == SessionEventType::SessionError) |
| 116 | + { |
| 117 | + if (auto* data = evt.try_as<SessionErrorData>()) |
| 118 | + error_message = data->message; |
| 119 | + else |
| 120 | + error_message = "Session error"; |
| 121 | + done = true; |
| 122 | + cv.notify_one(); |
| 123 | + } |
| 124 | + } |
| 125 | + ); |
| 126 | + |
| 127 | + // Send the message |
| 128 | + send(options).get(); |
| 129 | + |
| 130 | + // Wait for completion or timeout |
| 131 | + { |
| 132 | + std::unique_lock<std::mutex> lock(mtx); |
| 133 | + if (!cv.wait_for(lock, timeout, [&] { return done; })) |
| 134 | + { |
| 135 | + throw std::runtime_error("Timeout waiting for session to become idle"); |
| 136 | + } |
| 137 | + } |
| 138 | + |
| 139 | + if (error_message.has_value()) |
| 140 | + { |
| 141 | + throw std::runtime_error("Session error: " + *error_message); |
| 142 | + } |
| 143 | + |
| 144 | + return last_assistant_message; |
| 145 | + } |
| 146 | + ); |
| 147 | +} |
| 148 | + |
86 | 149 | // ============================================================================= |
87 | 150 | // Event Handling |
88 | 151 | // ============================================================================= |
|
0 commit comments