Spaces:
Sleeping
Sleeping
File size: 6,133 Bytes
b4a5305 f24ba1b b4a5305 f24ba1b b4a5305 a15f83f b4a5305 a15f83f b4a5305 a15f83f b4a5305 a15f83f b4a5305 a15f83f b4a5305 f24ba1b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | """Framework-neutral SpreadsheetBench actor-facing interface helpers."""
from __future__ import annotations
from pathlib import Path
import re
import openpyxl
# SkillOpt SpreadsheetBench mode=multi: up to 30 code-repair turns per task, a 600 s wall-clock
# budget per task (LLM latency included), and each execution feedback truncated to 3000 chars.
STEP_LIMIT = 30
TASK_TIME_BUDGET_S = 600.0
# SkillOpt stops issuing turns once fewer than this many seconds of the budget remain.
DEADLINE_MARGIN_S = 10.0
_ERROR_FEEDBACK_CHARS = 3000
_REPORT_LINE = re.compile(r"(\S+!?\w+):\s*got=(.+?),\s*expected=.+?\s*(PASS|FAIL)$")
def environment_description() -> str:
"""The SkillOpt SpreadsheetBench codegen system prompt, adapted only in its last sentence to
the native-tool transport (the script travels in the tool call's ``code`` field, not a fence)."""
return (
"You are an expert Python programmer specializing in spreadsheet manipulation. You will "
"be given a user instruction together with a preview of an input .xlsx file. Your job is "
"to write a single self-contained Python script that reads the input file at the path "
"stored in the variable INPUT_PATH, performs the requested manipulation, and saves the "
"result to OUTPUT_PATH. Use only the standard library, openpyxl, and pandas. Do not print "
"anything. Do not use input(). Do not hardcode file paths. Return ONLY the Python code in "
"the `code` field of the submit_script tool call."
)
def preview_workbook(
path: str | Path,
*,
max_rows: int = 5,
max_columns: int = 20,
) -> str:
"""The SkillOpt workbook preview: first 5 rows, 20 columns per sheet, coordinates and values."""
workbook = openpyxl.load_workbook(path, data_only=False)
chunks: list[str] = []
try:
for sheet_name in workbook.sheetnames:
sheet = workbook[sheet_name]
chunks.append(
f"## Sheet: {sheet_name} "
f"(dim={sheet.dimensions}, max_row={sheet.max_row}, max_col={sheet.max_column})"
)
for row in sheet.iter_rows(
min_row=1,
max_row=min(sheet.max_row, max_rows),
max_col=min(sheet.max_column, max_columns),
values_only=False,
):
cells: list[str] = []
for cell in row:
value = "" if cell.value is None else str(cell.value)
if len(value) > 40:
value = value[:37] + "..."
cells.append(f"{cell.coordinate}={value}")
chunks.append(" | ".join(cells))
if sheet.max_row > max_rows:
chunks.append(f"... ({sheet.max_row - max_rows} more rows)")
chunks.append("")
finally:
workbook.close()
return "\n".join(chunks)
def build_task_prompt(
instruction: str,
instruction_type: str,
answer_position: str,
preview: str,
) -> str:
"""The SkillOpt codegen user prompt, verbatim except the transport sentence."""
return (
f"# Instruction\n{instruction}\n"
f"\nInstruction type: {instruction_type}"
f"\nExpected answer position: {answer_position}\n\n"
f"# Input spreadsheet preview\n{preview}\n\n"
"# Task\n"
"Write a Python script that reads the workbook from the variable `INPUT_PATH`, "
"applies the instruction, and writes the modified workbook to `OUTPUT_PATH`. "
"Preserve all other cells unchanged. "
"The preview may be truncated \u2014 do not hardcode row counts or assume the data ends at "
"the last previewed row; iterate over all actual rows in the workbook instead. "
"Return only the Python code in the `code` field."
)
def extract_script(value: str) -> str:
"""Extract the first fenced code block, preserving legacy malformed-fence behavior."""
text = str(value)
if "```" not in text:
return text.strip()
start = text.find("```")
newline = text.find("\n", start)
end = text.find("```", newline + 1)
if newline == -1 or end == -1:
code = text.strip()
if code.startswith("```"):
first_newline = code.find("\n")
code = code[first_newline + 1 :] if first_newline >= 0 else ""
return code.strip()
return text[newline + 1 : end].strip()
def execution_error_feedback(error: str) -> str:
"""SkillOpt's execution-failure feedback turn, verbatim except the transport sentence."""
return (
"The code raised an error during execution:\n\n"
f"```\n{error[:_ERROR_FEEDBACK_CHARS]}\n```\n\n"
"Please fix the code and return a complete corrected Python script in the `code` field "
"of the submit_script tool call."
)
def eval_feedback(verification: str) -> str:
"""SkillOpt's training-only wrong-output feedback: the agent's own cell values marked WRONG,
expected values hidden, correct cells counted. Lines that are not per-cell comparisons
(missing sheets, truncation markers) are dropped, as in the original."""
wrong_lines: list[str] = []
n_correct = 0
for raw_line in verification.splitlines():
line = raw_line.strip()
if not line:
continue
match = _REPORT_LINE.match(line)
if match is None:
continue
cell, got_value, mark = match.groups()
if mark == "FAIL":
wrong_lines.append(f" {cell}: your output = {got_value} (WRONG)")
else:
n_correct += 1
lines = [
"Your code executed successfully but produced incorrect results.",
"The following cells have wrong values:",
]
lines.extend(wrong_lines)
if n_correct:
lines.append(f" ({n_correct} other cells are correct.)")
lines.append(
"\nPlease analyze the spreadsheet data more carefully and fix the code. "
"Return a complete corrected Python script in the `code` field of the submit_script "
"tool call."
)
return "\n".join(lines)
|