Command Parser

Extracts and executes embedded bracket actions from Luna's responses, plus intent parsing helpers for launch, map, Spotify, and research requests.

Overview

When Luna produces a response it may embed action commands inside square brackets — [LAUNCH:chrome], [BROWSE:https://...],[TASK:Buy milk|2025-06-01|low], etc. The command parser extracts these, and the executor carries them out.

ModuleContents
command_parser/commands.pyparse_commands(), execute_commands().
command_parser/away.pyuser_is_leaving(), response_is_farewell().
command_parser/intents.pyparse_user_launch_request(), parse_user_map_request(), parse_user_spotify_request().
command_parser/research.pyextract_direct_research_query(), extract_direct_dataset_query().
command_parser/coding.pyis_coding_request().

parse_commands()

Scans Luna's response text for embedded bracket commands and returns a list of parsed command dicts. Does not execute them.

signature
def parse_commands(
    response: str,
    user_message: str = "",
) -> list[dict]
example.py
from backend.services.command_parser import parse_commands

response = "Sure! [LAUNCH:spotify] [TASK:Buy milk|2025-06-01|low]"
cmds = parse_commands(response)
# [
#   {"type": "launch", "app": "spotify"},
#   {"type": "task", "title": "Buy milk", "due": "2025-06-01", "priority": "low"},
# ]

execute_commands()

Takes the list returned by parse_commands() and executes each command. Side effects: launching apps, opening URLs, writing to the database, calling Spotify, setting away state.

signature
def execute_commands(
    commands: list[dict],
    db: Session,
    conversation_id: int,
) -> None
example.py
from backend.services.command_parser import parse_commands, execute_commands
from backend.models.database import SessionLocal

db = SessionLocal()
cmds = parse_commands(luna_response, user_message)
execute_commands(cmds, db, conversation_id=42)
db.close()
💡
All errors inside execute_commands() are silently swallowed per command — one failing command doesn't block the others. Check logs if an action doesn't seem to execute.

Bracket syntax reference

Luna's system prompt teaches it to embed these brackets. Each is parsed by parse_commands():

BracketCommand typeFields
[AWAY]awayaction: "on", label: "away"|"bedtime"
[BROWSE:https://...]browseurl — blocked for weather/finance/crypto sites
[MAP:search:query]mapaction: "search", query
[MAP:route:destination]mapaction: "route", query
[MAP:close]mapaction: "close"
[SPOTIFY:query]spotifyquery
[SPOTIFY:queue query]spotify_queuequery
[LAUNCH:app name]launchapp
[WIDGET:kind|title|body]widgetkind, title, body
[TASK:title|due?|priority?]tasktitle, due (ISO date, optional), priority (default: medium)
[EVENT:title|datetime|duration?]eventtitle, datetime (ISO), duration (minutes, default: 60)

Browse blocklist

URLs matching weather, finance, or crypto domains are blocked from the[BROWSE] command (Luna is not supposed to open live data pages automatically). Affected domains include weather.com,finance.yahoo.com, coinmarketcap.com, and others.

Away detection

The away.py module provides two helper predicates used byparse_commands() and the chat pipeline:

signatures
def user_is_leaving(message: str) -> bool
def response_is_farewell(response: str) -> bool

If the user's message contains farewell phrases ("going to bed","see you later", "taking a break", …) or Luna's response is itself a farewell, an [AWAY] command is emitted with label"bedtime" when bed-related words are present, otherwise "away".

📌
Away detection only runs in the personal variant (LUNA_VARIANT=personal).

Intent parsing

These helpers are used by the chat router before sending messages to the LLM, to decide whether to route to a specialised handler:

signatures
def parse_user_launch_request(message: str) -> str | None
# Returns the app name to launch, or None

def parse_user_map_request(message: str) -> dict | None
# Returns {"action": "search"|"route", "query": str} or None

def parse_user_spotify_request(message: str) -> dict | None
# Returns {"action": "play"|"pause"|"next"|"prev", "query": str | None} or None
example.py
from backend.services.command_parser import (
    parse_user_launch_request,
    parse_user_map_request,
    parse_user_spotify_request,
)

parse_user_launch_request("open notepad")        # "notepad"
parse_user_map_request("directions to the gym")  # {"action": "route", "query": "the gym"}
parse_user_spotify_request("play some jazz")     # {"action": "play", "query": "jazz"}

Research query extraction

signatures
def extract_direct_research_query(message: str) -> str | None
# Detects explicit research requests ("research X", "look up X", "find info on X")

def extract_direct_dataset_query(message: str) -> str | None
# Detects dataset requests ("find a dataset of X", "get CSV data about X")

These are used by the chat router to bypass the main LLM and call the research skill directly when the user's intent is unambiguous.

Coding request detection

signature
def is_coding_request(message: str) -> bool

Returns True when the message is clearly a code-writing, debugging, or technical explanation request. Used by the chat router to redirect to the coding agent rather than the general chat pipeline.

example.py
from backend.services.command_parser import is_coding_request

is_coding_request("write a Python function to parse JSON")  # True
is_coding_request("what should I have for lunch?")          # False