https://www.boundaryml.com logo
🟡 Seeking common method for extracting thoughts i...
# questions
s
Hi all, wanted to check if there is an easy way to extract thoughts? I am using BAML in golang, for OpenAI I wrote a custom Tick handler but now I need to also use Gemini. Wondering if there is a common way to to extract thinking. If not, I have to write it for each provider. The goal is to extract and send thinking in conversation history so model can continue the though process instead of thinking on each turn. BAML doc suggested to use a reasoning field in the response but not sure if that's the right now. Open for suggestions!
v
yes! you can use
WithOnTick
as a function arg
s
Yes, that's what I did for OpenAI. But then I have to parse and extract the response of each provider. Wanted to check if BAML has that inbuilt for common providers.
Copy code
func (t *ThinkingExtractor) HandleTick(
    ctx context.Context,
    reason baml.TickReason,
    log baml.FunctionLog,
) baml.FunctionSignal {

    if t.doneProcessed {
        return nil
    }

    calls, err := log.Calls()
    if err != nil || len(calls) == 0 {
        return nil
    }

    lastCall := calls[len(calls)-1]

    streamCall, ok := lastCall.(baml.LLMStreamCall)
    if !ok {
        return nil
    }

    responses, err := streamCall.SSEChunks()
    if err != nil {
        return nil
    }

    for i := t.lastProcessedIndex; i < len(responses); i++ {
        response := responses[i]

        var data map[string]interface{}

        text, err := response.Text()
        if err != nil {
            continue
        }

        if err := json.Unmarshal([]byte(text), &data); err != nil {
            continue
        }

        eventType, _ := data["type"].(string)

        switch eventType {

        // 🧠 reasoning started (still comes as added)
        case "response.reasoning_summary_part.added":

            if !t.started {
                t.startTime = time.Now()
                t.started = true
            }

            select {
            case t.emitCh <- struct{}{}:
            default:
            }

        // ✅ NEW DONE EVENT
        case "response.output_item.done":

            if t.doneProcessed {
                continue
            }
v
we do have a
.raw_text
field available on the
FunctionLog
object!
4 Views