Choose how to run this agent
Download Agent
Choose how you want to use this agent:
Use Security Settings Key (Recommended)
Use the API key you've already saved in Security Settings. Quick and convenient!
- No need to re-enter API key
- Works offline after download
- Centralized key management
No API key found in Security Settings. Add one now
Enter API Key Manually
Enter your API key now for this specific agent download.
- Use different key for this agent
- One-time use (not saved)
- Works offline after download
Configure Agent Encryption
Description
Freelancer Tax Q&A Helper is a browser-executable AI agent template built on AgentOp. It runs entirely in the browser using Python (via Pyodide) and can be deployed without a server — just download the generated HTML file and open it locally or host it anywhere.
Source Code
# Freelancer Tax Q&A Helper - Python side
# Public functions (no leading underscore) become tools; we expose only process_user_query.
# Do not import heavy packages; keep prompt compact for local models.
from typing import List, Tuple
import asyncio
from textwrap import shorten
import js
# Tunables (use triple-bracket templating with defaults)
MAX_CONTEXT_CHARS = int('[[[MAX_CHARS|6000]]]')
MAX_MEMORY_MESSAGES = 8 # keep it small for local models
# Conversation memory: list of (user, assistant)
HISTORY: List[Tuple[str, str]] = []
SYSTEM_PROMPT = (
"You are a plain-language tax-question helper for freelancers and independent contractors. "
"Answer questions about deductions, quarterly estimated taxes, and self-employment tax. "
"Instructions:\n"
"- Give clear, friendly explanations in simple sentences.\n"
"- Start with a direct answer in 1-2 sentences.\n"
"- Then include: 'Why:' with the general rule.\n"
"- If helpful, add 'How to figure it:' with steps or a small example or quick math.\n"
"- Ask 1-2 clarifying questions if key info is missing.\n"
"- If the user states a jurisdiction, adapt to it. If not, assume U.S. federal rules and note when rules vary by state/country.\n"
"- Do not invent precise statutory citations. You may reference high-level sources like 'IRS Publication 334/535' as examples.\n"
"- If the topic is not tax, politely steer back to freelancer tax topics.\n"
"- Always end with exactly this one-line reminder: This isn't professional tax advice.\n"
"Formatting:\n"
"- Use short paragraphs or bullet points.\n"
"- Show simple calculations clearly.\n"
)
async def _llm_call(prompt: str, system_prompt: str) -> str:
"""Call the injected provider-neutral LLM from Python via JS.
Args:
prompt: The user/context prompt string.
system_prompt: The system instruction string.
"""
# window.callLLM(prompt, systemPrompt) is injected by the platform
try:
resp = await js.callLLM(prompt, system_prompt)
except Exception as e:
return f"Sorry, I couldn't reach the language model service. Please try again. (Error: {e})"
# resp should be a string
try:
return str(resp)
except Exception:
return "Sorry, I couldn't parse the model response. Please try again."
def _reset_state():
"""Reset in-memory conversation state (helper; not exposed as a tool)."""
HISTORY.clear()
def _build_context(jurisdiction: str) -> str:
"""Build textual conversation context limited by character budget.
Args:
jurisdiction: The jurisdiction hint selected by the user.
"""
parts: List[str] = []
jur = jurisdiction.strip() or "US"
parts.append(f"Jurisdiction: {jur}")
parts.append("You are assisting a self-employed freelancer with taxes.")
# Add recent history
if HISTORY:
parts.append("Conversation so far (most recent last):")
for u, a in HISTORY[-MAX_MEMORY_MESSAGES:]:
parts.append(f"User: {u}")
parts.append(f"Assistant: {a}")
context = "\n".join(parts)
# Truncate if needed
if len(context) > MAX_CONTEXT_CHARS:
context = context[-MAX_CONTEXT_CHARS:]
return context
async def process_user_query(query: str, jurisdiction: str = "US") -> str:
"""Handle a user query end-to-end: build context, call the LLM, update memory.
Args:
query: The user's tax question.
jurisdiction: Jurisdiction hint (e.g., 'US', 'UK').
"""
q = (query or "").strip()
if not q:
return "Please enter a freelancer tax question to begin. This isn't professional tax advice."
context = _build_context(jurisdiction)
# Compose final prompt: context + current turn
prompt = (
f"{context}\n\n"
f"User: {q}\n"
f"Assistant:"
)
answer = await _llm_call(prompt, SYSTEM_PROMPT)
# Ensure the mandatory reminder is present (add if missing)
reminder = "This isn't professional tax advice."
if reminder not in answer:
if answer.endswith("."):
answer = f"{answer}\n\n{reminder}"
else:
answer = f"{answer}.\n\n{reminder}"
# Update memory
try:
HISTORY.append((q, answer))
# Trim memory if it grows too large
if len(HISTORY) > MAX_MEMORY_MESSAGES * 2:
del HISTORY[: len(HISTORY) - MAX_MEMORY_MESSAGES]
except Exception:
pass
return answer
More by ozzo
ATS Resume Optimizer Agent
The ATS Resume Optimizer Agent helps you tailor your resume to specific job postings and stand out …
Contract Plain-Language Explainer Agent
Contracts are written by lawyers, for lawyers — but you’re the one signing them. The Contract Plain…
Data Analysis Agent
The Data Analysis Agent is a powerful, browser-based AI agent built on AgentOp that lets you explor…