Documentation Index Fetch the complete documentation index at: https://docs.hellofriday.ai/llms.txt
Use this file to discover all available pages before exploring further.
Functions
Extract a JSON object from a text string, with optional dataclass validation.
@overload
def parse_input ( prompt : str ) -> dict : ...
@overload
def parse_input ( prompt : str , schema : type[T]) -> T: ...
def parse_input ( prompt : str , schema : type | None = None ) -> Any: ...
Parameters:
Parameter Type Required Description promptstrYes The enriched prompt text from Friday schematype | NoneNo Dataclass type for typed extraction
Returns: dict or dataclass instance
Raises:
ValueError — No valid JSON object found in prompt
TypeError — Schema is not a dataclass
ValueError — JSON doesn’t match dataclass (missing required fields)
Example:
from dataclasses import dataclass
from friday_agent_sdk import parse_input
# Plain dict extraction
data = parse_input(prompt)
repo = data.get( "repository" )
branch = data.get( "branch" , "main" )
# Typed extraction
@dataclass
class Config :
repository: str
branch: str = "main"
dry_run: bool = False
config = parse_input(prompt, Config)
# config.repository, config.branch, config.dry_run available with types
parse_operation()
Extract an operation config using a discriminator field.
def parse_operation ( prompt : str , schemas : dict[ str , type[T]]) -> T: ...
Parameters:
Parameter Type Required Description promptstrYes The enriched prompt text schemasdict[str, type[T]]Yes Map of operation name to dataclass type
Returns: Dataclass instance for the matched operation
Raises: ValueError — No valid operation config found
Example:
from dataclasses import dataclass
from friday_agent_sdk import parse_operation
@dataclass
class CloneConfig :
operation: str # Must be "clone"
repository: str
branch: str = "main"
@dataclass
class DeployConfig :
operation: str # Must be "deploy"
environment: str
version: str
OPERATIONS = {
"clone" : CloneConfig,
"deploy" : DeployConfig,
}
config = parse_operation(prompt, OPERATIONS )
match config.operation:
case "clone" :
# config is typed as CloneConfig
handle_clone(config)
case "deploy" :
# config is typed as DeployConfig
handle_deploy(config)
Both functions search in this order:
Balanced-brace JSON objects — Hand-rolled scanner handles arbitrary nesting
Code-fenced JSON blocks — Extracts from ```json ... ```
Full prompt — Attempts to parse entire prompt as JSON
For parse_operation(), only JSON objects containing an "operation" field are considered, and the discriminator value selects the schema.
JSON in Markdown
Input may look like:
Task: Deploy the application
Here is the configuration:
```json
{ "operation" : "deploy" , "environment" : "production" , "version" : "1.2.3" }
```
Both parse_input() and parse_operation() extract the JSON block correctly.
Dataclass Validation
When using a schema:
Only fields defined in the dataclass are extracted (unknown keys filtered)
Missing required fields raise ValueError with clear message
Type hints are not enforced at runtime (Python limitation)
@dataclass
class StrictConfig :
required_field: str
optional_field: int = 0
# Raises: ValueError: missing {'required_field'}
config = parse_input( '{"optional_field": 5}' , StrictConfig)
# Succeeds: required_field="value", optional_field=5
config = parse_input(
'{"required_field": "value", "optional_field": 5, "extra": "ignored"}' ,
StrictConfig,
)
Error Messages
Clear errors for debugging:
# No JSON found
parse_input( "Just text without JSON" )
# ValueError: No valid JSON object found in prompt. Prompt starts with: Just text...
# Invalid JSON
parse_input( "{invalid json}" )
# ValueError: No valid JSON object found...
# Schema mismatch
parse_input( '{"wrong": "fields"}' , Config)
# ValueError: JSON parsed but doesn't match Config: missing {'repository'}
# Operation not found
parse_operation( '{"operation": "unknown"}' , { "clone" : CloneConfig})
# ValueError: No valid operation config found. Known operations: ['clone']...
Real Example: Jira Agent
from dataclasses import dataclass
from friday_agent_sdk import agent, err, ok, parse_operation
@dataclass
class IssueViewConfig :
operation: str
issue_key: str
@dataclass
class IssueSearchConfig :
operation: str
jql: str
max_results: int = 50
@dataclass
class IssueCreateConfig :
operation: str
project_key: str
summary: str
description: str | None = None
issue_type: str = "Bug"
OPERATIONS = {
"issue-view" : IssueViewConfig,
"issue-search" : IssueSearchConfig,
"issue-create" : IssueCreateConfig,
}
@agent ( id = "jira" , version = "1.0.0" , description = "Jira operations" )
def execute ( prompt , ctx ):
try :
config = parse_operation(prompt, OPERATIONS )
except ValueError as e:
return err( str (e))
match config.operation:
case "issue-view" :
return handle_view(config, ctx)
case "issue-search" :
return handle_search(config, ctx)
case "issue-create" :
return handle_create(config, ctx)
case _:
return err( f "Unknown operation: { config.operation } " )
When to Use
Function Use When parse_input(prompt)Single configuration, flexible parsing, no operation types parse_input(prompt, Schema)Single configuration, want typed fields parse_operation(prompt, schemas)Multiple operations, discriminated by "operation" field
Implementation Details
The balanced-brace scanner:
Handles arbitrary nesting depth (recursive objects/arrays)
Tracks string boundaries and escape sequences
Avoids miscounting braces inside string literals
Returns all valid JSON objects found, tries each in order
This hand-rolled approach is necessary because regex cannot handle arbitrary nesting depth reliably.
See Also
How to Handle Structured Input Task-oriented guide
Jira Agent Example Full operation dispatch pattern shown above