217 lines
5.7 KiB
Markdown
217 lines
5.7 KiB
Markdown
# Conversational Form API Reference
|
|
|
|
**Library:** `chatfield` Python package
|
|
|
|
API reference for building conversational form interviews. Powered by the Chatfield library.
|
|
|
|
## Contents
|
|
- Quick Start
|
|
- Builder API
|
|
- Interview Configuration
|
|
- Roles
|
|
- Fields
|
|
- Validation
|
|
- Special Field Types
|
|
- Transformations
|
|
- Cardinality
|
|
- Field Access
|
|
- Optional Fields
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
```python
|
|
from chatfield import chatfield, Interviewer
|
|
|
|
# Define
|
|
interview = (chatfield()
|
|
.field("name")
|
|
.desc("What is your full name?")
|
|
.must("include first and last")
|
|
.field("age")
|
|
.desc("Your age?")
|
|
.as_int()
|
|
.must("be between 18 and 120")
|
|
.build())
|
|
|
|
# Run
|
|
interviewer = Interviewer(interview)
|
|
user_input = None
|
|
while not interview._done:
|
|
message = interviewer.go(user_input)
|
|
print(f"Assistant: {message}")
|
|
if not interview._done:
|
|
user_input = input("You: ").strip()
|
|
|
|
# Access
|
|
print(interview.name, interview.age.as_int)
|
|
```
|
|
|
|
---
|
|
|
|
## Builder API
|
|
|
|
### Interview Configuration
|
|
|
|
```python
|
|
interview = (chatfield()
|
|
.type("Job Application") # Interview type
|
|
.desc("Collect applicant info") # Description
|
|
.build())
|
|
```
|
|
|
|
### Roles
|
|
|
|
```python
|
|
.alice() # Configure AI assistant
|
|
.type("Tax Assistant")
|
|
.trait("Professional and accurate")
|
|
.trait("Never provides tax advice")
|
|
|
|
.bob() # Configure user
|
|
.type("Taxpayer")
|
|
.trait("Speaks colloquially")
|
|
```
|
|
|
|
### Fields
|
|
|
|
```python
|
|
.field("email") # Define field (becomes interview.email)
|
|
.desc("What is your email?") # User-facing question
|
|
```
|
|
|
|
**All fields mandatory to populate** (must be non-`None` for `._done`). Content can be empty string `""`.
|
|
Exception: `.as_one()`, `.as_multi()`, and fields with strict validation require non-empty values.
|
|
|
|
### Validation
|
|
|
|
```python
|
|
.field("email")
|
|
.must("be valid email format") # Requirement (AND logic)
|
|
.must("not be disposable")
|
|
.reject("profanity") # Block pattern
|
|
.hint("Background: Company email preferred") # Advisory (not enforced)
|
|
```
|
|
|
|
### Hints
|
|
|
|
Hints provide context and guidance to Alice. **All hints must start with "Background:" or "Tooltip:"**
|
|
|
|
```python
|
|
# Background hints: Internal notes for Alice only (not mentioned to Bob)
|
|
.hint("Background: Convert Gregorian to Buddhist calendar (+543 years)")
|
|
.hint("Background: Optional per form instructions")
|
|
|
|
# Tooltip hints: May be shared with Bob if helpful
|
|
.hint("Tooltip: Your employer should provide this number")
|
|
.hint("Tooltip: Ask your supervisor if unsure")
|
|
```
|
|
|
|
**Background hints** are for Alice's internal use - she handles formatting/conversions transparently without mentioning them to Bob.
|
|
**Tooltip hints** may be shared with Bob to help clarify what information is needed.
|
|
|
|
### Special Field Types
|
|
|
|
```python
|
|
.field("sentiment_score")
|
|
.confidential() # Track silently, never ask Bob
|
|
|
|
.field("summary")
|
|
.conclude() # Compute after regular fields (auto-confidential)
|
|
```
|
|
|
|
### Transformations
|
|
|
|
LLM computes during collection. Access via `interview.field.as_*`
|
|
|
|
```python
|
|
.field("age").as_int() # → interview.age.as_int = 25
|
|
.field("price").as_float() # → interview.price.as_float = 99.99
|
|
.field("citizen").as_bool() # → interview.citizen.as_bool = True
|
|
.field("hobbies").as_list() # → interview.hobbies.as_list = ["reading", "coding"]
|
|
.field("config").as_json() # → interview.config.as_json = {"theme": "dark"}
|
|
.field("progress").as_percent() # → interview.progress.as_percent = 0.75
|
|
.field("greeting").as_lang("fr") # → interview.greeting.as_lang_fr = "Bonjour"
|
|
|
|
# Optional descriptions guide edge cases
|
|
.field("has_partners")
|
|
.as_bool("true if you have partners; false if not or N/A")
|
|
|
|
.field("quantity")
|
|
.as_int("parse as integer, ignore units")
|
|
|
|
# Named string casts for formatting
|
|
.field("ssn")
|
|
.must("be exactly 9 digits")
|
|
.as_str("formatted", "Format as ###-##-####")
|
|
# Access: interview.ssn.as_str_formatted → "123-45-6789"
|
|
```
|
|
|
|
**Validation vs. Casts:**
|
|
- **Validation** (`.must()`): Check content ("9 digits", "valid email")
|
|
- **Casts** (`.as_*()`): Provide format (hyphens, capitalization)
|
|
|
|
### Choice Cardinality
|
|
|
|
Select from predefined options:
|
|
|
|
```python
|
|
.field("tax_class")
|
|
.as_one("Individual", "C Corp", "S Corp") # Exactly one choice required
|
|
|
|
.field("dietary")
|
|
.as_nullable_one("Vegetarian", "Vegan") # Zero or one
|
|
|
|
.field("languages")
|
|
.as_multi("Python", "JavaScript", "Go") # One or more choices required
|
|
|
|
.field("interests")
|
|
.as_nullable_multi("ML", "Web Dev", "DevOps") # Zero or more
|
|
```
|
|
|
|
### Build
|
|
|
|
```python
|
|
.build() # Return Interview instance
|
|
```
|
|
|
|
---
|
|
|
|
## Field Access
|
|
|
|
**Dot notation** (regular fields):
|
|
```python
|
|
interview.name
|
|
interview.age.as_int
|
|
```
|
|
|
|
**Bracket notation** (special characters):
|
|
```python
|
|
interview["topmostSubform[0].Page1[0].f1_01[0]"] # PDF form fields
|
|
interview["user.name"] # Dots
|
|
interview["full name"] # Spaces
|
|
interview["class"] # Reserved words
|
|
```
|
|
|
|
---
|
|
|
|
## Optional Fields
|
|
|
|
Fields known to be optional (from PDF tooltip, nearby context, or instructions):
|
|
|
|
```python
|
|
.alice()
|
|
.trait("Records optional fields as empty string when user says blank/none/skip")
|
|
|
|
.field("middle_name")
|
|
.desc("Middle name")
|
|
.hint("Background: Optional per form instructions")
|
|
|
|
.field("extension")
|
|
.desc("Phone extension")
|
|
.hint("Background: Leave blank if none")
|
|
```
|
|
|
|
For optional **choices**, use `.as_nullable_one()` or `.as_nullable_multi()` (see examples above).
|