Skip to content
Open
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 sdk_v2/cpp/include/foundry_local/foundry_local_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ struct flInferenceApi {
/// Values are string representations; the implementation parses them for the appropriate type.
/// The request copies the data — the caller may release the pairs after this call.
FL_API_STATUS(Request_SetOptions, _In_ flRequest* request, _In_ const flKeyValuePairs* options);
/// Cancel an in-progress request.
/// Cancel the in-flight invocation of a request. This is a no-op while idle or after completion.
FL_API_STATUS(Request_Cancel, _In_ flRequest* request);

/* Response */
Expand Down
2 changes: 1 addition & 1 deletion sdk_v2/cpp/include/foundry_local/foundry_local_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ class Request {
/// Options for this request. Overrides session options for the duration of this request.
Request& SetOptions(const RequestOptions& options);

/// Cancel the current request. Inferencing will stop as soon as possible.
/// Cancel this request's in-flight invocation. This is a no-op while idle or after completion.
void Cancel();

const flRequest* native_handle() const noexcept { return handle_.get(); }
Expand Down
2 changes: 1 addition & 1 deletion sdk_v2/cpp/src/c_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1727,7 +1727,7 @@ FL_API_STATUS_IMPL(Request_CancelImpl, flRequest* request) {
if (!request) {
return MakeStatus(FOUNDRY_LOCAL_ERROR_INVALID_ARGUMENT, "null argument");
}
AsImpl(request)->canceled = true;
AsImpl(request)->Cancel();
Comment thread
bmehta001 marked this conversation as resolved.
return nullptr;
API_IMPL_END
}
Expand Down
37 changes: 20 additions & 17 deletions sdk_v2/cpp/src/inferencing/generative/audio/audio_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -240,15 +240,15 @@ void AudioSession::ProcessRequestImpl(const Request& request, Response& response
int prompt_tokens = generator->PromptTokenCount();

// Token-by-token generation with optional streaming.
// Check request.canceled each iteration — a streaming callback returning
// Check request cancellation each iteration — a streaming callback returning
// non-zero sets this flag asynchronously via CallbackHandler.
std::vector<std::string> token_texts;
token_texts.reserve(kInitialTokenCapacity);
auto streaming_callback = CreateCallbackHandler(request);
std::vector<std::unique_ptr<SpeechSegmentItem>> segments;
segments.reserve(kInitialTokenCapacity);

while (!generator->IsDone() && !request.canceled) {
while (!generator->IsDone() && !request.IsCancellationRequested()) {
generator->GenerateNextToken();
std::string token = generator->Decode();

Expand All @@ -262,7 +262,7 @@ void AudioSession::ProcessRequestImpl(const Request& request, Response& response
token_texts.push_back(std::move(token));
}

if (request.canceled) {
if (request.IsCancellationRequested()) {
generator->Cancel();
}
}
Expand All @@ -275,7 +275,7 @@ void AudioSession::ProcessRequestImpl(const Request& request, Response& response
response.items.push_back(BuildSpeechResult(std::move(text), std::move(segments)));

// Set finish reason
if (request.canceled) {
if (request.IsCancellationRequested()) {
response.finish_reason = FOUNDRY_LOCAL_FINISH_NONE;
} else {
response.finish_reason = FOUNDRY_LOCAL_FINISH_STOP;
Expand Down Expand Up @@ -358,7 +358,7 @@ void AudioSession::ProcessStreamingAudio(const AudioItem& format_item, ItemQueue
}

// 4. Read from queue until finished or cancelled
while (!request.canceled) {
while (!request.IsCancellationRequested()) {
auto item = queue.WaitAndPop(std::chrono::milliseconds(100));

if (!item) {
Expand All @@ -383,7 +383,7 @@ void AudioSession::ProcessStreamingAudio(const AudioItem& format_item, ItemQueue
}

// 5. Flush remaining buffered audio
if (!request.canceled) {
if (!request.IsCancellationRequested()) {
auto flush_tensors = processor->Flush();

if (flush_tensors) {
Expand All @@ -398,7 +398,7 @@ void AudioSession::ProcessStreamingAudio(const AudioItem& format_item, ItemQueue
const size_t full_text_size = full_text.size();
response.items.push_back(BuildSpeechResult(std::move(full_text), std::move(segments)));

if (request.canceled) {
if (request.IsCancellationRequested()) {
response.finish_reason = FOUNDRY_LOCAL_FINISH_NONE;
} else {
response.finish_reason = FOUNDRY_LOCAL_FINISH_STOP;
Expand Down Expand Up @@ -434,7 +434,7 @@ void AudioSession::DecodeTokens(OgaGenerator& generator, OgaTokenizerStream& tok
const std::unique_ptr<CallbackHandler>& callback,
const Request& request,
int& completion_tokens) {
while (!generator.IsDone() && !generator.IsSessionTerminated() && !request.canceled) {
while (!generator.IsDone() && !generator.IsSessionTerminated() && !request.IsCancellationRequested()) {
generator.GenerateNextToken();
auto next_tokens = generator.GetNextTokens();

Expand Down Expand Up @@ -508,7 +508,7 @@ void AudioSession::ProcessAudioTranscriptionJson(const std::string& request_json

// Generate token-by-token
std::string text;
while (!generator->IsDone() && !original_request.canceled) {
while (!generator->IsDone() && !original_request.IsCancellationRequested()) {
generator->GenerateNextToken();
std::string token = generator->Decode();

Expand All @@ -525,7 +525,7 @@ void AudioSession::ProcessAudioTranscriptionJson(const std::string& request_json
}
}

if (original_request.canceled) {
if (original_request.IsCancellationRequested()) {
generator->Cancel();
}
}
Expand All @@ -534,7 +534,7 @@ void AudioSession::ProcessAudioTranscriptionJson(const std::string& request_json
int completion_tokens = total_tokens - prompt_tokens;

// Set finish reason
if (original_request.canceled) {
if (original_request.IsCancellationRequested()) {
response.finish_reason = FOUNDRY_LOCAL_FINISH_NONE;
} else {
response.finish_reason = FOUNDRY_LOCAL_FINISH_STOP;
Expand Down Expand Up @@ -589,7 +589,8 @@ void AudioSession::DecodeNemotronTokens(OgaGenerator& generator, OgaTokenizerStr
int& completion_tokens) const {
const bool is_streaming = (streaming_callback != nullptr);

while (!generator.IsDone() && !generator.IsSessionTerminated() && !original_request.canceled) {
while (!generator.IsDone() && !generator.IsSessionTerminated() &&
!original_request.IsCancellationRequested()) {
generator.GenerateNextToken();
auto next_tokens = generator.GetNextTokens();
if (next_tokens.empty()) {
Expand Down Expand Up @@ -624,7 +625,7 @@ void AudioSession::RunNemotronDecodePass(std::unique_ptr<OgaNamedTensors> tensor
const std::unique_ptr<CallbackHandler>& streaming_callback,
const std::string& response_id, const Request& original_request,
int& completion_tokens) const {
if (!tensors || original_request.canceled) {
if (!tensors || original_request.IsCancellationRequested()) {
return;
}

Expand All @@ -636,7 +637,7 @@ void AudioSession::RunNemotronDecodePass(std::unique_ptr<OgaNamedTensors> tensor
void AudioSession::ProcessNemotronFileTranscription(const AudioTranscriptionRequest& req,
const Request& original_request,
Response& response) {
if (original_request.canceled) {
if (original_request.IsCancellationRequested()) {
response.finish_reason = FOUNDRY_LOCAL_FINISH_NONE;
return;
}
Expand Down Expand Up @@ -673,18 +674,20 @@ void AudioSession::ProcessNemotronFileTranscription(const AudioTranscriptionRequ
int completion_tokens = 0;

constexpr size_t kNemotronSamplesPerChunk = 1600; // 100ms at 16kHz
for (size_t offset = 0; offset < samples.size() && !original_request.canceled;
for (size_t offset = 0;
offset < samples.size() && !original_request.IsCancellationRequested();
offset += kNemotronSamplesPerChunk) {
size_t count = std::min(kNemotronSamplesPerChunk, samples.size() - offset);
RunNemotronDecodePass(processor->Process(samples.data() + offset, count), *generator, *tokenizer_stream, text,
streaming_callback, response_id, original_request, completion_tokens);
}
if (!original_request.canceled) {
if (!original_request.IsCancellationRequested()) {
RunNemotronDecodePass(processor->Flush(), *generator, *tokenizer_stream, text, streaming_callback, response_id,
original_request, completion_tokens);
}

response.finish_reason = original_request.canceled ? FOUNDRY_LOCAL_FINISH_NONE : FOUNDRY_LOCAL_FINISH_STOP;
response.finish_reason =
original_request.IsCancellationRequested() ? FOUNDRY_LOCAL_FINISH_NONE : FOUNDRY_LOCAL_FINISH_STOP;
// Nemotron file-transcription path feeds audio tensors directly and does not expose prompt token accounting.
response.usage.prompt_tokens = 0;
response.usage.completion_tokens = completion_tokens;
Expand Down
Loading
Loading