@qingflow-tech/qingflow-cli 1.1.49 → 1.1.50-beta.1
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 -410
- 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/builder/workflow/03-flow-patterns.md +13 -5
- package/skills/qingflow-cli/reference/builder/workflow/07-stage4-validate-spec.md +5 -3
- package/skills/qingflow-cli/reference/builder/workflow/08-stage5-apply-verify.md +1 -1
- package/skills/qingflow-cli/reference/builder/workflow/11-troubleshooting.md +1 -1
- package/skills/qingflow-cli/reference/builder/workflow/workflow-schema.json +1665 -1738
- 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-cli/scripts/workflow/validate_flow_spec.py +48 -46
- package/skills/qingflow-common/SKILL.md +10 -17
- package/src/qingflow_mcp/backend_client.py +142 -12
- package/src/qingflow_mcp/builder_facade/flow_validation.py +569 -0
- package/src/qingflow_mcp/builder_facade/service.py +749 -6
- package/src/qingflow_mcp/builder_facade/workflow_spec.py +154 -2
- package/src/qingflow_mcp/cli/commands/__init__.py +2 -1
- package/src/qingflow_mcp/cli/commands/auth.py +1 -1
- package/src/qingflow_mcp/cli/commands/builder.py +57 -41
- 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 +4 -1
- package/src/qingflow_mcp/cli/formatters.py +159 -4
- package/src/qingflow_mcp/cli/main.py +4 -1
- package/src/qingflow_mcp/config.py +60 -0
- package/src/qingflow_mcp/public_surface.py +9 -0
- package/src/qingflow_mcp/resource_uri.py +241 -0
- package/src/qingflow_mcp/response_trim.py +53 -5
- package/src/qingflow_mcp/server.py +2 -0
- package/src/qingflow_mcp/server_app_builder.py +57 -2
- package/src/qingflow_mcp/server_app_user.py +10 -3
- package/src/qingflow_mcp/tools/ai_builder_tools.py +374 -41
- package/src/qingflow_mcp/tools/app_tools.py +52 -13
- 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/login_link_tools.py +34 -6
- package/src/qingflow_mcp/tools/record_tools.py +11 -46
- package/src/qingflow_mcp/tools/resource_read_tools.py +13 -0
|
@@ -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,
|
|
@@ -6,6 +6,7 @@ from typing import Any
|
|
|
6
6
|
from ..errors import QingflowApiError, backend_code_int, is_auth_like_error, raise_tool_error
|
|
7
7
|
from ..json_types import JSONObject
|
|
8
8
|
from ..list_type_labels import SYSTEM_VIEW_DEFINITIONS
|
|
9
|
+
from ..resource_uri import try_build_resource_uri
|
|
9
10
|
from ..solution.compiler.icon_utils import workspace_icon_config
|
|
10
11
|
from .app_tools import _analysis_supported_for_view_type
|
|
11
12
|
from .base import ToolBase
|
|
@@ -227,6 +228,17 @@ class ResourceReadTools(ToolBase):
|
|
|
227
228
|
"message": f"view_get supports exporting `{view_id}`, but the export call still needs an explicit `app_key` from the parent app context.",
|
|
228
229
|
}
|
|
229
230
|
)
|
|
231
|
+
uri = None
|
|
232
|
+
if resolved_app_key:
|
|
233
|
+
uri, uri_warning = try_build_resource_uri(
|
|
234
|
+
ws_id=session_profile.selected_ws_id,
|
|
235
|
+
resource_type="view",
|
|
236
|
+
app_key=resolved_app_key,
|
|
237
|
+
view_kind="custom",
|
|
238
|
+
view_key=view_key,
|
|
239
|
+
)
|
|
240
|
+
if uri_warning:
|
|
241
|
+
warnings.append(uri_warning)
|
|
230
242
|
return {
|
|
231
243
|
"profile": profile,
|
|
232
244
|
"ws_id": session_profile.selected_ws_id,
|
|
@@ -249,6 +261,7 @@ class ResourceReadTools(ToolBase):
|
|
|
249
261
|
],
|
|
250
262
|
"analysis_supported": _analysis_supported_for_view_type(raw_view_type or None),
|
|
251
263
|
"export_capability": export_capability,
|
|
264
|
+
**({"uri": uri} if uri else {}),
|
|
252
265
|
},
|
|
253
266
|
}
|
|
254
267
|
|