Excel generator with AI-powered data analysis, charts, formulas, and web search. Create spreadsheets, analyze CSV/Excel/PDF files, generate HTML reports, and get real-time data.
When the user's request is a continuation of a previous Excel task, you MUST use the --session parameter.
How to detect a continuation task:
How to use session_id:
💡 To continue this conversation, use: --session xxx--session xxx to the command:python3 scripts/excel_api_client.py "user's follow-up request" \
--session abc123def456 \
--language zh-CN \
--log-path "$EXCEL_LOG" \
> /dev/null 2>&1 &
⛔ If you don't pass --session, the agent will start fresh and lose all previous context!
NEVER use the read tool on user-provided files (Excel, PDF, CSV, images, etc.).
The backend agent will read and process files itself. You only need to:
--files parameterReading files wastes time and causes timeouts. Just upload and let the backend handle everything.
Excel tasks take 5-25 minutes. You MUST run the script in background and poll the log every 5 seconds to keep the UI responsive and avoid timeouts.
EXCEL_LOG=/tmp/excel_$(date +%s).log
python3 scripts/excel_api_client.py "user query" \
--files "/path/to/file1.xlsx" "/path/to/file2.pdf" \
--language zh-CN \
--log-path "$EXCEL_LOG" \
> /dev/null 2>&1 &
echo "Log: $EXCEL_LOG"
STRICT RULES — no exceptions:
- Poll every 60 seconds by calling exec tool repeatedly. Excel tasks take 10-25 minutes.
- Only show the LAST TASK PROGRESS UPDATE. Do NOT output full log or summarize it.
- NEVER restart the task. The Excel agent handles errors internally and will auto-recover.
- Ignore all errors in the log (e.g.,
❌,Missing parameter,jupyter_executeerrors). These are normal — the agent will retry automatically.
Every 60 seconds, run this exact sequence (call exec tool each time, do NOT use while loop):
# Step 1: Wait 60 seconds
sleep 60
# Step 2: Check progress
echo "=== Progress Update ==="
grep -A8 "TASK PROGRESS UPDATE" "$EXCEL_LOG" | tail -10
# Step 3: Check if done
grep -E "\[DONE\]|All done" "$EXCEL_LOG" | tail -1
[DONE] or ✅ All done! → stop polling, read final output with tail -30 "$EXCEL_LOG", then deliver results.[DONE] or All done.CRITICAL: Output ONLY the current status. Do NOT repeat or accumulate previous status messages. Each update should be a single, fresh line.
After each log read, output ONLY ONE LINE showing the current status:
[Main stage] | [current action] | Elapsed: Xs
Example (output only this single line, nothing else):
Data Processing | Generating charts | Elapsed: 120s
Map TASK PROGRESS UPDATE to main stages:
| Progress contains | Main stage |
|---|---|
| "读取" / "read" / "load" | Loading data |
| "分析" / "analysis" | Data analysis |
| "图表" / "chart" / "visualization" | Generating charts |
| "Excel" / "xlsx" | Creating Excel file |
| "HTML" / "报告" / "report" | Generating report |
| "保存" / "save" / "output" | Saving output |
Example status updates:
Loading data | Reading Excel files | Elapsed: 30s
Data analysis | Processing stock data | Elapsed: 90s
Generating report | Creating HTML analysis | Elapsed: 180s
Do NOT:
tail -50 or full log contentA professional skill for generating and updating high-quality Excel files using a sophisticated backend service with AI-powered data analysis, charting, formula validation, and report generation capabilities.
Before using this skill, authentication must be completed. Run the auth script first:
# Authenticate: checks env token / cached token / browser login
python3 <skill-dir>/scripts/skywork_auth.py || exit 1
Token priority:
SKYBOT_TOKEN → if set, use directly~/.skywork_token → validate via API, if valid, use itIMPORTANT - Login URL handling: If script output contains a line starting with [LOGIN_URL], you MUST immediately send that URL to the user in a clickable message (e.g. "Please open this link to log in: <url>"). The user may be in an environment where the browser cannot open automatically, so always surface the login URL.
Use this skill when the user wants to:
The agent supports multiple output formats:
The backend agent automatically chooses the appropriate format based on the user's request. Just pass the user's natural language request directly.
The backend service is particularly powerful for tasks that benefit from specialized Excel knowledge, formula validation, and visual quality assurance.
The skill uses a ReAct agent loop that:
jupyter_execute for data manipulation, validate_excel_formulas, validate_excel_charts, etc./workspace/output/ (automatically registered for download)When sending requests to the Excel Agent:
[Current time: 2026-03-14] User request: Get Xiaomi stock price this week...
/Users/xxx/report.xlsx → report.xlsx)upload_file() for each file before calling run_agent(). If you cannot find the file at the specified path, ask the user to provide the correct file path before proceeding. Pass the returned file_ids to run_agent() so the backend can access the uploaded filesfile_id and filename (e.g., "file_id abc123 is sales_data.xlsx")Always start by checking if the backend service is healthy:
from excel_api_client import ExcelAgentClient
# Auto-login: will prompt browser login if no token available
client = ExcelAgentClient()
if not client.health_check():
print("Service unavailable or authentication failed")
exit(1)
print("Service is ready!")
If the user mentions existing files or you have files to analyze, upload them first:
from excel_api_client import ExcelAgentClient
client = ExcelAgentClient() # Auto-login
# Upload file
file_id = client.upload_file("/path/to/data.xlsx")
print(f"Uploaded: {file_id}")
Send the user's request to the backend via SSE streaming endpoint:
from excel_api_client import ExcelAgentClient
client = ExcelAgentClient() # Auto-login
# Run agent with streaming progress
output_files = client.run_agent(
message="Create a sales report with charts",
file_ids=["uploaded_file_id"], # Optional
language="zh-CN" # or "en-US"
)
# output_files contains: [{"file_id": "...", "name": "...", "size": ...}, ...]
The client handles all SSE streaming internally and displays progress to stdout.
After the agent completes, download the output files for the user:
from excel_api_client import ExcelAgentClient
client = ExcelAgentClient() # Auto-login
# Download all output files
for f in output_files:
client.download_file(f["file_id"], f"./{f['name']}")
CLI output includes both paths — when using the command-line script, it automatically outputs:
📁 Local: — the absolute local file path where the file was downloaded☁️ OSS: — the cloud download URL for sharingWhen summarizing results to the user, always include BOTH the local file path AND the OSS download link from the script output.
The SSE endpoint returns real-time progress updates. Always display these to the user so they understand what's happening:
progress events: Show the agent's reasoning and thought processtool_start events: Indicate when tools like jupyter_execute start runningtool_result events: Show whether tools succeeded and their output summariesThis transparency is crucial because Excel generation can take 30-120 seconds for complex tasks.
The backend fully supports multi-turn sessions via session_id. This is critical for iterative refinement tasks.
session_id at the start of a conversation (e.g., uuid.uuid4()[:12])session_id to ALL subsequent run_agent() calls in the same conversation/workspace/<session_id>/output/ directoryfrom excel_api_client import ExcelAgentClient
client = ExcelAgentClient()
# First turn: don't pass session_id, server generates one and returns it
output_files, session_id = client.run_agent(
message="Create a sales report with Q1 data"
)
# session_id is now available, e.g., "a1b2c3d4e5f6"
# Second turn: pass the returned session_id
output_files, _ = client.run_agent(
message="Add a pie chart showing product category breakdown",
session_id=session_id # ← Use the returned session_id
)
# Third turn: continue with same session_id
output_files, _ = client.run_agent(
message="Change the chart colors to blue theme",
session_id=session_id
)
import uuid
# Generate session_id upfront
session_id = str(uuid.uuid4())[:12]
# All calls use the same session_id
client.run_agent(message="Create a report", session_id=session_id)
client.run_agent(message="Add charts", session_id=session_id)
# First turn (no --session, server generates one)
python scripts/excel_api_client.py "Create a sales report"
# Output: 💡 To continue this conversation, use: --session abc123def456
# Second turn (use the printed session_id)
python scripts/excel_api_client.py "Add charts to the report" --session abc123def456
To clear conversation history and start fresh with the same session_id:
# Option 1: Use new_session=True (clears history but keeps session_id)
output_files, _ = client.run_agent(message="...", session_id=session_id, new_session=True)
# Option 2: Don't pass session_id to get a fresh one
output_files, new_session_id = client.run_agent(message="...")
session_id values: Agent treats each call as independentsession_id: If you don't pass one, capture the returned value for subsequent callsCommon issues and how to handle them:
clarification_needed event fires, pause and get user input before continuingInsufficient benefit. Please upgrade your account at {url} — reply per "How to reply when benefit is insufficient" belowWhen you detect the above, reply in the user's current language — do not echo the English message. Use this pattern:
[Upgrade now →](url) or the equivalent in their language.at https://... part).The backend supports both Chinese and English:
"language": "zh-CN" - Chinese prompts and output (default)"language": "en-US" - English prompts and outputChoose based on the user's language or their explicit preference.
The backend agent has access to these powerful tools:
jupyter_execute: Run Python code with pandas, openpyxl, matplotlib, etc. for data manipulation and Excel generationvalidate_excel_formulas: Verify Excel formulas are syntactically correct before savingvalidate_excel_charts: Render charts as images to visually verify they look correctexcel_data_llm_analysis: Perform semantic analysis on large datasets (translation, classification, summarization)grep_by_keyword: Search uploaded files for specific contentread_document_pages: Extract text from PDF/DOCX filesexcel_visual_agent: Extract structured data from images/PDFs into Excelparallel_search_full: Search the web for data to include in reportsbrowse_urls: Fetch content from specific URLstodo_write: Maintain task lists to prevent goal drift during complex multi-step tasksYou don't need to explicitly call these tools - the agent automatically decides which tools to use based on the user's request.
Common scenarios (see Core Workflow for full code):
| Pattern | Description | Key Points |
|---|---|---|
| Create from Scratch | Create Excel from scratch | Pass message directly, no file_ids needed |
| Analyze Existing File | Analyze an existing file | Call upload_file() first, then pass file_ids |
| Generate HTML Report | Generate an HTML report | Ideal for sharing and presentation, format auto-selected |
| Multi-Turn Refinement | Iterative multi-turn edits | Keep the same session_id |
| Merge Multiple Files | Merge multiple files | Upload multiple files, process in one request |
Example requests:
All output files are saved to /workspace/<session_id>/output/ on the backend server. The agent automatically:
output_files event:
{
"file_id": "abc123xyz",
"name": "report.xlsx",
"size": 15360,
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"path": "/tmp/excel_agent_workspace/session_123/output/report.xlsx",
"oss_url": "https://xxx.oss-cn-xxx.aliyuncs.com/excel-agent/session_123/report.xlsx"
}
/api/download/{file_id} (fallback if OSS unavailable)After the agent completes, you MUST display the OSS download links to the user:
✅ Report generated successfully!
📥 Download link:
- report.xlsx: https://picture-search.skywork.ai/skills/upload/2026-03-14/xxx.xlsx
💾 Local file: /Users/xxx/.openclaw/workspace/report.xlsx
sandbox:// or [filename](sandbox://...) format - these are not clickableoss_url is not available, inform user the file was saved locally and provide the full pathBe specific in requests: The more detail you provide, the better the output
Use the helper script: For convenience, use scripts/excel_api_client.py which handles SSE streaming, file upload/download, and error handling
Monitor progress: Always display progress events to the user - Excel generation can take time for complex tasks
Handle clarifications: If the agent sends a clarification_needed event, pause and get user input before continuing
Session management: Use consistent session_ids for related tasks to maintain context
Verify outputs: After downloading files, inform the user of the file location and suggest they open it to verify results
"Unauthorized (401)"
python scripts/skywork_auth.py --login to re-authenticate"Connection timeout"
--timeout 1500 for very complex tasks"File not found after download"
output_files event was received before attempting download"Agent produces wrong output"
Use the bundled scripts/excel_api_client.py for streamlined integration:
from excel_api_client import ExcelAgentClient
# Initialize with auto-login (recommended)
client = ExcelAgentClient()
# Check if service is ready
if not client.health_check():
print("Service unavailable or authentication failed.")
exit(1)
# Upload files if needed
file_ids = [client.upload_file("data.xlsx")]
# Run agent with progress streaming
output_files = client.run_agent(
message="Create a summary report with charts",
file_ids=file_ids
)
# Download results
for f in output_files:
client.download_file(f["file_id"], f"./{f['name']}")
⚠️ Important Security Practices:
qGXpDd6H...cv0)~/.skywork_token (user home directory, not in project)See scripts/excel_api_client.py and scripts/skywork_auth.py for the full implementation.