Fix Feishu sheet data writes
This commit is contained in:
+54
-11
@@ -2634,10 +2634,10 @@ def _create_feishu_online_spreadsheet(
|
||||
create_params: dict[str, Any] = {'title': title}
|
||||
if folder_token and folder_token.strip():
|
||||
create_params['folder_token'] = folder_token.strip()
|
||||
rendered, metadata = runtime.call_tool(
|
||||
rendered, metadata = _call_feishu_mcp_tool_checked(
|
||||
runtime,
|
||||
'sheet_ops',
|
||||
arguments={'action': 'create', 'params': create_params},
|
||||
server_name=FEISHU_MCP_SERVER_NAME,
|
||||
max_chars=API_TOOL_CONTENT_MAX_CHARS,
|
||||
timeout_seconds=60.0,
|
||||
)
|
||||
@@ -2645,13 +2645,14 @@ def _create_feishu_online_spreadsheet(
|
||||
if not spreadsheet_token:
|
||||
raise DataAgentInputError('飞书表格已创建,但没有解析到 spreadsheet token')
|
||||
|
||||
sheet_refs = _discover_feishu_sheet_refs(runtime, spreadsheet_token)
|
||||
for index, sheet_data in enumerate(sheets):
|
||||
rows = sheet_data['rows']
|
||||
if not rows:
|
||||
continue
|
||||
if index == 0:
|
||||
sheet_ref = sheet_refs[0] if sheet_refs else 'Sheet1'
|
||||
# 新建飞书表格默认会带一个名为 Sheet1 的工作表。
|
||||
# 不从 spreadsheet meta 里取顶层 title,避免把文件名误当成工作表名。
|
||||
sheet_ref = 'Sheet1'
|
||||
else:
|
||||
sheet_ref = _create_feishu_worksheet(
|
||||
runtime,
|
||||
@@ -2663,6 +2664,44 @@ def _create_feishu_online_spreadsheet(
|
||||
return rendered, metadata
|
||||
|
||||
|
||||
def _call_feishu_mcp_tool_checked(
|
||||
runtime: MCPRuntime,
|
||||
tool_name: str,
|
||||
*,
|
||||
arguments: dict[str, Any],
|
||||
max_chars: int,
|
||||
timeout_seconds: float,
|
||||
) -> tuple[str, dict[str, Any]]:
|
||||
rendered, metadata = runtime.call_tool(
|
||||
tool_name,
|
||||
arguments=arguments,
|
||||
server_name=FEISHU_MCP_SERVER_NAME,
|
||||
max_chars=max_chars,
|
||||
timeout_seconds=timeout_seconds,
|
||||
)
|
||||
error_message = _extract_feishu_mcp_error(rendered)
|
||||
if metadata.get('is_error') or error_message:
|
||||
raise DataAgentInputError(error_message or f'飞书 MCP 工具 {tool_name} 调用失败')
|
||||
return rendered, metadata
|
||||
|
||||
|
||||
def _extract_feishu_mcp_error(text: str) -> str | None:
|
||||
payload = _parse_first_json_object(text)
|
||||
if not isinstance(payload, dict):
|
||||
return None
|
||||
error_value = payload.get('error')
|
||||
if not error_value:
|
||||
return None
|
||||
suggestion = payload.get('suggestion')
|
||||
code = payload.get('code')
|
||||
parts = [str(error_value)]
|
||||
if code is not None:
|
||||
parts.append(f'code={code}')
|
||||
if suggestion:
|
||||
parts.append(str(suggestion))
|
||||
return ';'.join(parts)
|
||||
|
||||
|
||||
def _load_file_as_feishu_sheets(file_path: Path) -> list[dict[str, Any]]:
|
||||
suffix = file_path.suffix.lower()
|
||||
if suffix == '.csv':
|
||||
@@ -2762,10 +2801,10 @@ def _extract_feishu_spreadsheet_token(text: str) -> str | None:
|
||||
|
||||
def _discover_feishu_sheet_refs(runtime: MCPRuntime, spreadsheet_token: str) -> list[str]:
|
||||
try:
|
||||
rendered, _metadata = runtime.call_tool(
|
||||
rendered, _metadata = _call_feishu_mcp_tool_checked(
|
||||
runtime,
|
||||
'sheet_ops',
|
||||
arguments={'action': 'meta', 'params': {'url_or_token': spreadsheet_token}},
|
||||
server_name=FEISHU_MCP_SERVER_NAME,
|
||||
max_chars=API_TOOL_CONTENT_MAX_CHARS,
|
||||
timeout_seconds=60.0,
|
||||
)
|
||||
@@ -2785,7 +2824,11 @@ def _extract_feishu_sheet_refs(text: str) -> list[str]:
|
||||
raw_title = value.get('title') or value.get('name')
|
||||
if isinstance(raw_id, str) and raw_id.strip():
|
||||
refs.append(raw_id.strip())
|
||||
elif isinstance(raw_title, str) and raw_title.strip():
|
||||
elif (
|
||||
isinstance(raw_title, str)
|
||||
and raw_title.strip()
|
||||
and ('index' in value or 'row_count' in value or 'col_count' in value)
|
||||
):
|
||||
refs.append(raw_title.strip())
|
||||
for child in value.values():
|
||||
visit(child)
|
||||
@@ -2816,7 +2859,8 @@ def _create_feishu_worksheet(
|
||||
index: int,
|
||||
) -> str:
|
||||
sheet_title = _clean_feishu_sheet_title(title) or f'Sheet{index + 1}'
|
||||
rendered, _metadata = runtime.call_tool(
|
||||
rendered, _metadata = _call_feishu_mcp_tool_checked(
|
||||
runtime,
|
||||
'sheet_ops',
|
||||
arguments={
|
||||
'action': 'add_sheet',
|
||||
@@ -2826,7 +2870,6 @@ def _create_feishu_worksheet(
|
||||
'index': index,
|
||||
},
|
||||
},
|
||||
server_name=FEISHU_MCP_SERVER_NAME,
|
||||
max_chars=API_TOOL_CONTENT_MAX_CHARS,
|
||||
timeout_seconds=60.0,
|
||||
)
|
||||
@@ -2848,7 +2891,8 @@ def _write_feishu_sheet_rows(
|
||||
chunk = rows[start : start + FEISHU_SPREADSHEET_WRITE_BATCH_ROWS]
|
||||
start_row = start + 1
|
||||
end_row = start + len(chunk)
|
||||
runtime.call_tool(
|
||||
_call_feishu_mcp_tool_checked(
|
||||
runtime,
|
||||
'sheet_ops',
|
||||
arguments={
|
||||
'action': 'write',
|
||||
@@ -2858,7 +2902,6 @@ def _write_feishu_sheet_rows(
|
||||
'values': json.dumps(chunk, ensure_ascii=False),
|
||||
},
|
||||
},
|
||||
server_name=FEISHU_MCP_SERVER_NAME,
|
||||
max_chars=API_TOOL_CONTENT_MAX_CHARS,
|
||||
timeout_seconds=60.0,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user