@qingflow-tech/qingflow-cli 1.1.59 → 1.1.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/npm/lib/runtime.mjs +29 -13
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/skills/qingflow-cli/SKILL.md +92 -430
- package/skills/qingflow-cli/manifest.yaml +1 -1
- package/skills/qingflow-cli/reference/00-INDEX.md +4 -4
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_ADMIN_CHEATSHEET.md +1 -1
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md +3 -137
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_EXPLORATION_REPORT.md +6 -4
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_FIELD_DATA_TYPES.md +14 -14
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_MEMBER_CHEATSHEET.md +20 -19
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_ONE_SHOT_CHEATSHEET.md +18 -14
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_RECORD_CREATE_WORKFLOW.md +7 -12
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_RECORD_UPDATE_WORKFLOW.md +2 -1
- package/skills/qingflow-cli/reference/core/QINGFLOW_CLI_ADMIN_CHEATSHEET.md +1 -1
- package/skills/qingflow-cli/reference/core/QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md +76 -95
- package/skills/qingflow-cli/reference/core/QINGFLOW_CLI_EXPLORATION_REPORT.md +6 -4
- package/skills/qingflow-cli/reference/core/QINGFLOW_CLI_FIELD_DATA_TYPES.md +13 -13
- package/skills/qingflow-cli/reference/core/QINGFLOW_CLI_MEMBER_CHEATSHEET.md +20 -19
- package/skills/qingflow-cli/reference/core/QINGFLOW_CLI_ONE_SHOT_CHEATSHEET.md +18 -14
- package/skills/qingflow-cli/reference/data/README.md +32 -0
- package/skills/qingflow-cli/reference/record/QINGFLOW_CLI_RECORD_SPECIALIZED_WORKFLOW.md +50 -0
- package/skills/qingflow-cli/reference/record/QINGFLOW_CLI_RECORD_UPDATE_WORKFLOW.md +2 -1
- package/skills/qingflow-cli/reference/record/analysis/README.md +21 -113
- package/skills/qingflow-cli/reference/record/analysis/analysis-gotchas.md +10 -10
- package/skills/qingflow-cli/reference/record/analysis/analysis-patterns.md +9 -9
- package/skills/qingflow-cli/reference/record/analysis/business-context.md +1 -1
- package/skills/qingflow-cli/reference/record/analysis/confidence-reporting.md +10 -10
- package/skills/qingflow-cli/reference/record/analysis/data-access-playbook.md +52 -80
- package/skills/qingflow-cli/reference/record/analysis/pandas-recipes.md +2 -2
- package/skills/qingflow-common/SKILL.md +7 -4
- package/src/qingflow_mcp/cli/commands/__init__.py +2 -1
- package/src/qingflow_mcp/cli/commands/data.py +134 -0
- package/src/qingflow_mcp/cli/commands/record.py +1 -1
- package/src/qingflow_mcp/cli/context.py +3 -0
- package/src/qingflow_mcp/cli/formatters.py +97 -1
- package/src/qingflow_mcp/public_surface.py +5 -0
- package/src/qingflow_mcp/server.py +2 -0
- package/src/qingflow_mcp/server_app_user.py +4 -0
- package/src/qingflow_mcp/tools/csv_export.py +168 -0
- package/src/qingflow_mcp/tools/data_tools.py +284 -0
- package/src/qingflow_mcp/tools/record_tools.py +11 -46
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import csv
|
|
4
3
|
import html
|
|
5
4
|
import mimetypes
|
|
6
5
|
import json
|
|
@@ -34,6 +33,7 @@ from ..list_type_labels import (
|
|
|
34
33
|
)
|
|
35
34
|
from .base import ToolBase
|
|
36
35
|
from .directory_tools import _directory_has_more, _directory_items
|
|
36
|
+
from .csv_export import CsvShardWriter
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
DEFAULT_QUERY_PAGE_SIZE = 50
|
|
@@ -2284,57 +2284,22 @@ class RecordTools(ToolBase):
|
|
|
2284
2284
|
}
|
|
2285
2285
|
|
|
2286
2286
|
run_dir = _record_access_run_dir()
|
|
2287
|
-
run_dir.mkdir(parents=True, exist_ok=True)
|
|
2288
2287
|
header = ["record_id"] + [str(field["column_name"]) for field in fields_payload]
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
def close_shard() -> None:
|
|
2297
|
-
nonlocal file_handle, writer, shard_rows
|
|
2298
|
-
if file_handle is None:
|
|
2299
|
-
return
|
|
2300
|
-
path = Path(file_handle.name)
|
|
2301
|
-
file_handle.close()
|
|
2302
|
-
files.append(
|
|
2303
|
-
{
|
|
2304
|
-
"local_path": str(path),
|
|
2305
|
-
"row_count": shard_rows,
|
|
2306
|
-
"part": len(files) + 1,
|
|
2307
|
-
}
|
|
2308
|
-
)
|
|
2309
|
-
file_handle = None
|
|
2310
|
-
writer = None
|
|
2311
|
-
shard_rows = 0
|
|
2312
|
-
|
|
2313
|
-
def ensure_writer() -> Any:
|
|
2314
|
-
nonlocal file_handle, writer, shard_part
|
|
2315
|
-
if writer is not None:
|
|
2316
|
-
return writer
|
|
2317
|
-
shard_part += 1
|
|
2318
|
-
path = run_dir / f"records-{shard_part:04d}.csv"
|
|
2319
|
-
file_handle = path.open("w", newline="", encoding="utf-8-sig")
|
|
2320
|
-
writer = csv.writer(file_handle)
|
|
2321
|
-
writer.writerow(header)
|
|
2322
|
-
return writer
|
|
2288
|
+
shard_writer = CsvShardWriter(
|
|
2289
|
+
output_dir=run_dir,
|
|
2290
|
+
file_prefix="records",
|
|
2291
|
+
header=header,
|
|
2292
|
+
shard_rows=DEFAULT_RECORD_ACCESS_SHARD_ROWS,
|
|
2293
|
+
)
|
|
2323
2294
|
|
|
2324
2295
|
def write_record(apply_id: int | None, answer_list: list[JSONValue]) -> None:
|
|
2325
|
-
nonlocal row_count, shard_rows
|
|
2326
2296
|
if apply_id is None:
|
|
2327
2297
|
return
|
|
2328
|
-
if shard_rows >= DEFAULT_RECORD_ACCESS_SHARD_ROWS:
|
|
2329
|
-
close_shard()
|
|
2330
|
-
csv_writer = ensure_writer()
|
|
2331
2298
|
values: list[str] = [_public_record_id_text(apply_id) or ""]
|
|
2332
2299
|
for field in selected_fields:
|
|
2333
2300
|
answer = _find_answer_for_field(answer_list, field)
|
|
2334
2301
|
values.append(_record_access_csv_cell(_normalize_answer_field_value_for_output(answer, field)))
|
|
2335
|
-
|
|
2336
|
-
row_count += 1
|
|
2337
|
-
shard_rows += 1
|
|
2302
|
+
shard_writer.write(values)
|
|
2338
2303
|
|
|
2339
2304
|
current_page = 1
|
|
2340
2305
|
has_more = False
|
|
@@ -2374,7 +2339,7 @@ class RecordTools(ToolBase):
|
|
|
2374
2339
|
break
|
|
2375
2340
|
page = fetch_page(current_page, BACKEND_RECORD_ACCESS_PAGE_SIZE)
|
|
2376
2341
|
finally:
|
|
2377
|
-
close_shard()
|
|
2342
|
+
shard_writer.close_shard()
|
|
2378
2343
|
|
|
2379
2344
|
if stopped_reason == "TIME_BUDGET_EXCEEDED":
|
|
2380
2345
|
warnings.append(_record_access_time_budget_warning(reported_total=reported_total, fetched_pages=fetched_pages))
|
|
@@ -2399,11 +2364,11 @@ class RecordTools(ToolBase):
|
|
|
2399
2364
|
"view_id": view_route.view_id,
|
|
2400
2365
|
"format": "csv",
|
|
2401
2366
|
"local_dir": str(run_dir),
|
|
2402
|
-
"row_count": row_count,
|
|
2367
|
+
"row_count": shard_writer.row_count,
|
|
2403
2368
|
"complete": complete,
|
|
2404
2369
|
"truncated": not complete,
|
|
2405
2370
|
"safe_for_final_conclusion": safe_for_final_conclusion,
|
|
2406
|
-
"files": files,
|
|
2371
|
+
"files": shard_writer.files,
|
|
2407
2372
|
"fields": fields_payload,
|
|
2408
2373
|
"warnings": warnings,
|
|
2409
2374
|
"verification": verification_payload,
|