falaw.operations.llm#
LLM-driven tools: text completion, screenplay → Scene IR, IR editing.
These wrap fal-ai/any-llm so the agent (or the user) can invoke an LLM inline as part of a falaw workflow — e.g. parsing a treatment into a structured Scene, or rewriting a Beat from a directorial note.
We intentionally keep these thin. The contract is: any-llm is the
universal LLM endpoint, you pick the model via model, and we return
plain Python (str or parsed dict).
Functions
|
Use the LLM to apply a directorial note to a Beat. |
|
Apply a cross-cutting note: LLM proposes per-beat edits, we apply them. |
|
Single-shot LLM completion. |
|
Single-shot LLM completion that also reports what it cost. |
|
Convert prose screenplay text into a Scene IR via an LLM call. |
Classes
|
What one eager LLM call cost — the record the eager path never kept. |
- class falaw.operations.llm.LlmReceipt(application, model, cache_hit, chars_in, chars_out, tokens_in=None, tokens_out=None, estimated_cost_usd=None, cost_source='unknown')[source]#
Bases:
objectWhat one eager LLM call cost — the record the eager path never kept.
The falaw half of falaw#50’s option B: the eager
llm_complete()returned a bare string, so LLM spend was invisible to every accounting surface — not because estimates wereNone, but because *nothing was recorded at all* (the field signature: real dollars spent besideplans: 0). A caller that books receipts usesllm_complete_with_receipt()and gets this alongside the text.Field semantics, honest by construction:
chars_in/chars_outare measured facts (prompt+system in, response text out).tokens_in/tokens_outare best-effort from the raw response’s usage block (OpenAIprompt_tokens/completion_tokensand Anthropicinput_tokens/output_tokensshapes).Nonemeans unrecorded by the provider response, never zero.estimated_cost_usdis0.0on a cache hit (nothing was billed), else fal’s published per-request price for the routed model, read off the rate table (falaw.llm_ceiling_usd()) — an estimate, not an observed bill. It is the routed model and not thefal-ai/any-llmrecord because the record carries fal’s standard tier, and a premium routed model bills ten times that: pricing every turn from the record under-reported premium spend tenfold in the ledger a consumer sums (falaw#55).Noneonly when nothing can price it at all.cost_sourcesays which of those cases produced the number, so a receipt consumer never has to guess:"cache_hit","rate_table:per_call","registry:<kind>"(the fallback for a model the table does not price), or"unknown".
- falaw.operations.llm.apply_note_to_beat(beat, note, *, model='anthropic/claude-sonnet-4.5')[source]#
Use the LLM to apply a directorial note to a Beat.
- Return type:
- falaw.operations.llm.apply_note_to_scene(scene, note, *, model='anthropic/claude-sonnet-4.5')[source]#
Apply a cross-cutting note: LLM proposes per-beat edits, we apply them.
- Return type:
- falaw.operations.llm.llm_complete(prompt, *, system='', model='anthropic/claude-sonnet-4.5', temperature=0.7, extra=None)[source]#
Single-shot LLM completion. Returns the assistant text.
Delegates to
llm_complete_with_receipt()(one argument-construction site, so the two spellings share one cache identity) and discards the receipt. A caller that accounts for spend wants the receipt variant.- Return type:
- falaw.operations.llm.llm_complete_with_receipt(prompt, *, system='', model='anthropic/claude-sonnet-4.5', temperature=0.7, extra=None)[source]#
Single-shot LLM completion that also reports what it cost.
Same arguments, same wire call, same cache identity as
llm_complete()— the receipt is a side channel, observed from the call this function was making anyway (the cache layer’scache_hitevent, the response’s usage block, the registry’s estimate). Library surface only — deliberately NOT a registered tool: the tool surface keeps the one string-returningllm_complete.- Return type: