https://www.boundaryml.com logo
Warning error
# general
y
I know I have definitely ask this before but getting a pesky warming:
'action' is a type alias HistoryAction (resolves to (class SpeakAction | class WriteCodeAction | class HighlightCodeAction | class TerminalAction | class UserResponseAction)), expected class
Snippets:
Copy code
baml
type HistoryAction = SpeakAction | WriteCodeAction | HighlightCodeAction | TerminalAction | UserResponseAction

// Unified template for all modes - handles all action types in HistoryAction
// Note: USER_PROMPT is filtered out before passing to BAML, so not handled here
template_string FormatPreviousActions(actions: HistoryAction[]) #"
<PREVIOUS_ACTIONS>
{% if actions | length > 0 %}
{% for action in actions %}
- type: {{ action.type }}
{% if action.type == "SPEAK" %}
  speakerId: {{ action.speakerId }}
  content: {{ action.content }}
  tone: {{ action.tone }}
{% elif action.type == "WRITE_CODE" or action.type == "HIGHLIGHT_CODE" %}
  description: {{ action.description }}                                     # <----- The error is here
{% elif action.type == "TERMINAL" %}
  command: {{ action.command }}
{% elif action.type == "USER_RESPONSE" %}
  content: {{ action.content }}
{% endif %}
{% endfor %}
{% else %}
(No previous actions - just starting this section)
{% endif %}
</PREVIOUS_ACTIONS>
"#
Any help would be appreciated
g
Taking a look now!
I can reproduce this when some of the classes in the union that gets aliased lack one of the fields I use. Can you share the class definitions? It may just be a matter of an unhelpful warning message.
y
Here you go:
Copy code
// =============================================================================
// ACTION DEFINITIONS
// =============================================================================
// All action classes for script generation (narrative and answer scripts)

// -----------------------------------------------------------------------------
// ACTION CLASSES
// -----------------------------------------------------------------------------

class SpeakAction {
  type "SPEAK" @description("Dialogue from a speaker. Use for explanations, responses, and conversation.")
  speakerId int @description("ID of the speaker delivering this dialogue. Use the primary instructor for answers, secondary speakers can chime in briefly.")
  content string @description("The dialogue text to be spoken. Keep it conversational and natural.")
  tone string @description("Styling hint for speech synthesis (e.g., 'informative', 'encouraging', 'friendly', 'curious')")

  @@stream.done
}

class WriteCodeAction {
  type "WRITE_CODE" @description("Describe code to write. Use sparingly - prefer HIGHLIGHT_CODE for existing code. Coding agent interprets this with live codebase context. Emit BEFORE explaining in dialogue.")
  description string @description("Natural language description of what code to write and where (e.g., 'Add a messages key to the AgentState TypedDict in agent_state.py')")

  @@stream.done
}

class HighlightCodeAction {
  type "HIGHLIGHT_CODE" @description("Draw attention to existing code. Prefer this over WRITE_CODE when referencing code that already exists. Emit BEFORE explaining in dialogue.")
  description string @description("Natural language description of which code to highlight (e.g., 'Highlight the messages key in the AgentState TypedDict in agent_state.py')")

  @@stream.done
}

class TerminalAction {
  type "TERMINAL" @description("Execute a terminal command. Use for running scripts, installing packages, or demonstrating CLI tools.")
  command string @description("The terminal command to execute")

  @@stream.done
}

class UserPromptAction {
  type "USER_PROMPT" @description("Literal string USER_PROMPT")
  promptType ("question" | "proceed") @description("'question' asks user for text input, 'proceed' shows a continue button")
  question string @description(#"
    A concise question or prompt to display to the user.
    For 'question' type: the specific question being asked (e.g., 'What approach would you use to handle authentication?').
    For 'proceed' type: a contextual continuation prompt (e.g., 'Ready to move on to implementing the API?').
  "#)

  @@stream.done
}

class UserResponseAction {
  type "USER_RESPONSE" @description("Captures what the user said. Inserted by caller, not generated by BAML.")
  content string @description("The user's spoken or typed response")
}

class UnitCompleteAction {
  type "UNIT_COMPLETE" @description("Signals the narrative unit is complete. Emit only when all realization points have been covered (Socratic mode) or auto-appended by handler (Guided mode).")

  @@stream.done
}

// -----------------------------------------------------------------------------
// TYPE UNIONS
// -----------------------------------------------------------------------------

// INPUT TYPE: What can appear in conversation history (previousActions in all functions)
// Contains AI-generated content + user responses
// Note: USER_PROMPT is filtered out before passing to BAML (it's just a repeat of the last SPEAK)
type HistoryAction = SpeakAction | WriteCodeAction | HighlightCodeAction | TerminalAction | UserResponseAction
g
Okie doke. The issue is that we don't do very complicated type narrowing in jinja expressions. I got rid of 3/4 of the warnings by fixing a bug around field access under type alias. The remaining 1/4 come from narrowing for things like
if (a.type == This or a.type == That)
- we don't do disjunctive narrowing at all (so our jinja typechecker doesn't know that
a
will have the fields that are in both
This
and
That
. I'm spiking a solution now.
y
Ah. I see. Cool. Let me know how i can get rid of the warning
g
When do you see the warnings? During
baml-cli generate
?
y
Nope. Its in vs code
Happy to jumb on a call to help debug
Hey @greg (BAML) , just checking in. Is there any solution or work around?
g
Yes, my tech bud. I merged a fix today and it will be available in the next release! Unfortunately I don’t think there is a way to disable warnings, in the meantime.
y
I got patience. Im sure I can survive
Really appreciate this!
g
Thanks for the report 😄