dataops-sdk 0.4.2__tar.gz → 0.4.4__tar.gz

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.
Files changed (97) hide show
  1. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/PKG-INFO +1 -1
  2. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/__init__.py +3 -1
  3. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/__init__.py +9 -0
  4. dataops_sdk-0.4.4/src/dataops_sdk/schemas/tag.py +144 -0
  5. dataops_sdk-0.4.4/src/dataops_sdk/schemas/wiki.py +120 -0
  6. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/__init__.py +21 -0
  7. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/skill.py +113 -2
  8. dataops_sdk-0.4.4/src/dataops_sdk/services/tag.py +315 -0
  9. dataops_sdk-0.4.4/src/dataops_sdk/services/wiki.py +194 -0
  10. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/workflow.py +6 -4
  11. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk.egg-info/PKG-INFO +1 -1
  12. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk.egg-info/SOURCES.txt +4 -0
  13. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/README.md +0 -0
  14. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/pyproject.toml +0 -0
  15. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/setup.cfg +0 -0
  16. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/constants.py +0 -0
  17. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/exceptions.py +0 -0
  18. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/__init__.py +0 -0
  19. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/datasource_factory.py +0 -0
  20. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/__init__.py +0 -0
  21. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/config.py +0 -0
  22. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/constants.py +0 -0
  23. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/instance.py +0 -0
  24. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/nacos_exception.py +0 -0
  25. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/naming_param.py +0 -0
  26. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/naming_request.py +0 -0
  27. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/naming_response.py +0 -0
  28. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/preserved_metadata_key.py +0 -0
  29. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/schemas/nacos/service.py +0 -0
  30. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/__init__.py +0 -0
  31. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/common.py +0 -0
  32. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/dbConn_base.py +0 -0
  33. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/dbConn_sync.py +0 -0
  34. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/duckdb_manager.py +0 -0
  35. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/file_transfer_base.py +0 -0
  36. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/ftp_file_transfer.py +0 -0
  37. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/nacos.py +0 -0
  38. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/neo4j_sync.py +0 -0
  39. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/queue_base.py +0 -0
  40. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/queue_kafka.py +0 -0
  41. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/sftp_file_transfer.py +0 -0
  42. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/runner/utils/websocket_client.py +0 -0
  43. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/alarm.py +0 -0
  44. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/api.py +0 -0
  45. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/common.py +0 -0
  46. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/data_table.py +0 -0
  47. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/datasource.py +0 -0
  48. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/dict_.py +0 -0
  49. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/enums.py +0 -0
  50. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/group.py +0 -0
  51. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/hazard.py +0 -0
  52. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/meta.py +0 -0
  53. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/query.py +0 -0
  54. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/report.py +0 -0
  55. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/skill.py +0 -0
  56. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/sql_query_ast.py +0 -0
  57. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/table.py +0 -0
  58. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/user.py +0 -0
  59. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/widget.py +0 -0
  60. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/schemas/workflow.py +0 -0
  61. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/alarm.py +0 -0
  62. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/api.py +0 -0
  63. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/auth.py +0 -0
  64. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/data_table.py +0 -0
  65. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/dataset.py +0 -0
  66. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/datasource.py +0 -0
  67. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/dict_.py +0 -0
  68. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/group.py +0 -0
  69. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/hazard.py +0 -0
  70. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/meta.py +0 -0
  71. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/metrics.py +0 -0
  72. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/ref.py +0 -0
  73. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/report.py +0 -0
  74. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/table.py +0 -0
  75. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/services/widget.py +0 -0
  76. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/session.py +0 -0
  77. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/tiptap/__init__.py +0 -0
  78. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/tiptap/builder.py +0 -0
  79. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/tiptap/constants.py +0 -0
  80. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/tiptap/markdown_parser.py +0 -0
  81. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/tiptap/models.py +0 -0
  82. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/tiptap/parse_utils.py +0 -0
  83. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/tiptap/render_utils.py +0 -0
  84. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/tiptap/renderers.py +0 -0
  85. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/tiptap/tool.py +0 -0
  86. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/utils/__init__.py +0 -0
  87. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/utils/common.py +0 -0
  88. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/utils/log.py +0 -0
  89. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk/utils/utils.py +0 -0
  90. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk.egg-info/dependency_links.txt +0 -0
  91. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk.egg-info/requires.txt +0 -0
  92. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/src/dataops_sdk.egg-info/top_level.txt +0 -0
  93. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/tests/test_constants.py +0 -0
  94. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/tests/test_exceptions.py +0 -0
  95. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/tests/test_session.py +0 -0
  96. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/tests/test_utils.py +0 -0
  97. {dataops_sdk-0.4.2 → dataops_sdk-0.4.4}/tests/test_websocket_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataops-sdk
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: Python SDK for the DataOps platform.
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -95,6 +95,8 @@ from .services import ( # noqa: F401
95
95
  service_ref_forward,
96
96
  service_set_application,
97
97
  service_skill_call_by_code,
98
+ service_skill_download,
99
+ service_skill_update,
98
100
  service_skill_upload,
99
101
  service_skill_upload_sub_file,
100
102
  service_start_workflow,
@@ -107,4 +109,4 @@ from .services import ( # noqa: F401
107
109
  )
108
110
  from .session import dataops_base_url_context, request_context
109
111
 
110
- __version__ = "0.4.2"
112
+ __version__ = "0.4.4"
@@ -43,6 +43,7 @@ from .meta import (
43
43
  from .query import PageParam, SqlCondition, SqlFilter, SqlQueryParam, SqlSort
44
44
  from .report import ReportMeta, ReportMetaData
45
45
  from .skill import DataSkill, DataSkillSubFile, MetaSkill, SkillCallResult
46
+ from .tag import TagBrief, TagEntityType, TagTreeNode
46
47
  from .table import (
47
48
  ColumnItem,
48
49
  DataBaseColumnDictExternal,
@@ -53,4 +54,12 @@ from .table import (
53
54
  )
54
55
  from .user import Application, UserInfo
55
56
  from .widget import WidgetMeta, WidgetMetaData
57
+ from .wiki import (
58
+ KbType,
59
+ KnowledgeBase,
60
+ KnowledgeDocument,
61
+ KnowledgeSearchResult,
62
+ WikiPage,
63
+ WikiPageResult,
64
+ )
56
65
  from .workflow import DataWorkflow, MetaWorkflow
@@ -0,0 +1,144 @@
1
+ """元标签 (meta tag) Schema 定义.
2
+
3
+ 对应后端 ``MetaTagController``(``/data/meta/tag``)的树节点与实体关联摘要。
4
+ ``type`` 表示被标注的实体类型(如 skill / agent),不是 ``MetaType``。
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from datetime import datetime
10
+ from enum import StrEnum
11
+ from typing import Annotated
12
+
13
+ from pydantic import AliasChoices, BaseModel, ConfigDict, Field
14
+
15
+
16
+ class TagEntityType(StrEnum):
17
+ """常见标签作用域(实体类型)提示枚举;后端仍接受任意字符串."""
18
+
19
+ SKILL = "skill"
20
+ AGENT = "agent"
21
+ REPORT = "report"
22
+ WIDGET = "widget"
23
+
24
+
25
+ class TagBrief(BaseModel):
26
+ """实体已绑定标签的简要信息(``rel/list`` 返回)."""
27
+
28
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
29
+
30
+ cuid: Annotated[
31
+ str,
32
+ Field(description="标签 cuid", validation_alias=AliasChoices("cuid", "CUID")),
33
+ ]
34
+ title: Annotated[
35
+ str | None,
36
+ Field(description="标题", validation_alias=AliasChoices("title", "TITLE")),
37
+ ] = None
38
+ color: Annotated[
39
+ str | None,
40
+ Field(description="颜色", validation_alias=AliasChoices("color", "COLOR")),
41
+ ] = None
42
+ parentId: Annotated[
43
+ str | None,
44
+ Field(
45
+ description="父标签 cuid",
46
+ validation_alias=AliasChoices("parentId", "parent_id", "PARENT_ID"),
47
+ ),
48
+ ] = None
49
+ icon: Annotated[
50
+ str | None,
51
+ Field(description="图标", validation_alias=AliasChoices("icon", "ICON")),
52
+ ] = None
53
+
54
+
55
+ class TagTreeNode(BaseModel):
56
+ """标签树节点(``/tree`` 返回)."""
57
+
58
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
59
+
60
+ cuid: Annotated[
61
+ str,
62
+ Field(description="标签 cuid", validation_alias=AliasChoices("cuid", "CUID")),
63
+ ]
64
+ tenantId: Annotated[
65
+ str | None,
66
+ Field(
67
+ description="租户 ID",
68
+ validation_alias=AliasChoices("tenantId", "tenant_id", "TENANT_ID"),
69
+ ),
70
+ ] = None
71
+ prodCode: Annotated[
72
+ str | None,
73
+ Field(
74
+ description="应用编码",
75
+ validation_alias=AliasChoices("prodCode", "prod_code", "PROD_CODE"),
76
+ ),
77
+ ] = None
78
+ parentId: Annotated[
79
+ str | None,
80
+ Field(
81
+ description="父标签 cuid",
82
+ validation_alias=AliasChoices("parentId", "parent_id", "PARENT_ID"),
83
+ ),
84
+ ] = None
85
+ type: Annotated[
86
+ str | None,
87
+ Field(description="实体类型作用域", validation_alias=AliasChoices("type", "TYPE")),
88
+ ] = None
89
+ code: Annotated[
90
+ str | None,
91
+ Field(description="标签编码", validation_alias=AliasChoices("code", "CODE")),
92
+ ] = None
93
+ title: Annotated[
94
+ str | None,
95
+ Field(description="标题", validation_alias=AliasChoices("title", "TITLE")),
96
+ ] = None
97
+ icon: Annotated[
98
+ str | None,
99
+ Field(description="图标", validation_alias=AliasChoices("icon", "ICON")),
100
+ ] = None
101
+ color: Annotated[
102
+ str | None,
103
+ Field(description="颜色", validation_alias=AliasChoices("color", "COLOR")),
104
+ ] = None
105
+ sort: Annotated[
106
+ float | None,
107
+ Field(description="排序", validation_alias=AliasChoices("sort", "SORT")),
108
+ ] = None
109
+ remark: Annotated[
110
+ str | None,
111
+ Field(description="备注", validation_alias=AliasChoices("remark", "REMARK")),
112
+ ] = None
113
+ createUser: Annotated[
114
+ str | None,
115
+ Field(
116
+ description="创建人",
117
+ validation_alias=AliasChoices("createUser", "create_user", "CREATE_USER"),
118
+ ),
119
+ ] = None
120
+ createTime: Annotated[
121
+ datetime | str | None,
122
+ Field(
123
+ description="创建时间",
124
+ validation_alias=AliasChoices("createTime", "create_time", "CREATE_TIME"),
125
+ ),
126
+ ] = None
127
+ lastModifyUser: Annotated[
128
+ str | None,
129
+ Field(
130
+ description="修改人",
131
+ validation_alias=AliasChoices("lastModifyUser", "last_modify_user", "LAST_MODIFY_USER"),
132
+ ),
133
+ ] = None
134
+ lastModifyTime: Annotated[
135
+ datetime | str | None,
136
+ Field(
137
+ description="修改时间",
138
+ validation_alias=AliasChoices("lastModifyTime", "last_modify_time", "LAST_MODIFY_TIME"),
139
+ ),
140
+ ] = None
141
+ children: Annotated[
142
+ list[TagTreeNode],
143
+ Field(default_factory=list, description="子标签"),
144
+ ]
@@ -0,0 +1,120 @@
1
+ """Wiki / 知识库 Schema 定义.
2
+
3
+ 对应后端 ``data-ops-wiki`` 的 ``WikiApiController``(``/data/wiki/*``)返回结构。
4
+ 字段通过 ``validation_alias`` / ``AliasChoices`` 兼容 snake_case 与 weKnora 原始键名。
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from enum import StrEnum
10
+ from typing import Annotated, Generic, TypeVar
11
+
12
+ from pydantic import AliasChoices, BaseModel, ConfigDict, Field
13
+
14
+ T = TypeVar("T")
15
+
16
+
17
+ class KbType(StrEnum):
18
+ """知识库类型."""
19
+
20
+ DOCUMENT = "document"
21
+ FAQ = "faq"
22
+ WIKI = "wiki"
23
+
24
+
25
+ class KnowledgeBase(BaseModel):
26
+ """知识库."""
27
+
28
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
29
+
30
+ id: Annotated[str, Field(description="知识库 ID")]
31
+ name: Annotated[str, Field(description="知识库名称")]
32
+ description: Annotated[str | None, Field(description="描述")] = None
33
+ type: Annotated[str | None, Field(description="类型:document/faq/wiki")] = None
34
+ knowledge_count: Annotated[int | None, Field(description="文档数量", alias="knowledgeCount")] = None
35
+ chunk_count: Annotated[int | None, Field(description="切片数量", alias="chunkCount")] = None
36
+ created_at: Annotated[str | None, Field(description="创建时间")] = None
37
+ updated_at: Annotated[str | None, Field(description="更新时间")] = None
38
+
39
+
40
+ class KnowledgeDocument(BaseModel):
41
+ """知识库文档."""
42
+
43
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
44
+
45
+ id: Annotated[str, Field(description="文档 ID")]
46
+ title: Annotated[str | None, Field(description="标题")] = None
47
+ file_name: Annotated[str | None, Field(description="文件名", alias="fileName")] = None
48
+ file_type: Annotated[str | None, Field(description="文件类型", alias="fileType")] = None
49
+ parse_status: Annotated[str | None, Field(description="解析状态", alias="parseStatus")] = None
50
+ source: Annotated[str | None, Field(description="来源")] = None
51
+ type: Annotated[str | None, Field(description="类型")] = None
52
+ knowledge_base_id: Annotated[
53
+ str | None, Field(description="所属知识库", alias="knowledgeBaseId")
54
+ ] = None
55
+ created_at: Annotated[str | None, Field(description="创建时间")] = None
56
+
57
+
58
+ class KnowledgeSearchResult(BaseModel):
59
+ """关键词检索结果."""
60
+
61
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
62
+
63
+ id: Annotated[str | None, Field(description="结果 ID")] = None
64
+ chunk_id: Annotated[str | None, Field(description="切片 ID", alias="chunkId")] = None
65
+ title: Annotated[str | None, Field(description="标题")] = None
66
+ content: Annotated[str | None, Field(description="内容片段")] = None
67
+ score: Annotated[float | None, Field(description="相关度分数")] = None
68
+ kb_id: Annotated[str | None, Field(description="知识库 ID")] = None
69
+ knowledge_base_id: Annotated[
70
+ str | None, Field(description="知识库 ID", alias="knowledgeBaseId")
71
+ ] = None
72
+ kb_name: Annotated[str | None, Field(description="知识库名称", alias="kbName")] = None
73
+ knowledge_id: Annotated[str | None, Field(description="文档 ID", alias="knowledgeId")] = None
74
+ knowledge_title: Annotated[
75
+ str | None, Field(description="文档标题", alias="knowledgeTitle")
76
+ ] = None
77
+ file_type: Annotated[str | None, Field(description="文件类型", alias="fileType")] = None
78
+
79
+
80
+ class WikiPage(BaseModel):
81
+ """Wiki 页面."""
82
+
83
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
84
+
85
+ id: Annotated[str | None, Field(description="页面 ID")] = None
86
+ slug: Annotated[str, Field(description="页面 slug")]
87
+ title: Annotated[str | None, Field(description="标题")] = None
88
+ page_type: Annotated[str | None, Field(description="页面类型", alias="pageType")] = None
89
+ status: Annotated[str | None, Field(description="状态")] = None
90
+ summary: Annotated[str | None, Field(description="摘要")] = None
91
+ content: Annotated[str | None, Field(description="正文")] = None
92
+ wiki_path: Annotated[str | None, Field(description="Wiki 路径")] = None
93
+ knowledge_base_id: Annotated[
94
+ str | None, Field(description="所属知识库", alias="knowledgeBaseId")
95
+ ] = None
96
+
97
+
98
+ class WikiPageResult(BaseModel, Generic[T]):
99
+ """分页结果."""
100
+
101
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
102
+
103
+ items: Annotated[
104
+ list[T],
105
+ Field(
106
+ description="列表",
107
+ validation_alias=AliasChoices("list", "items"),
108
+ serialization_alias="list",
109
+ ),
110
+ ] = []
111
+ total: Annotated[int, Field(description="总数")] = 0
112
+ page: Annotated[int, Field(description="页码")] = 1
113
+ page_size: Annotated[
114
+ int,
115
+ Field(description="每页条数", validation_alias=AliasChoices("page_size", "pageSize")),
116
+ ] = 20
117
+ has_more: Annotated[
118
+ bool | None,
119
+ Field(description="是否还有更多", validation_alias=AliasChoices("has_more", "hasMore")),
120
+ ] = None
@@ -106,8 +106,10 @@ from .skill import (
106
106
  service_skill_call_by_code,
107
107
  service_skill_call_by_name,
108
108
  service_skill_delete_sub_file,
109
+ service_skill_download,
109
110
  service_skill_get_subfile_by_code,
110
111
  service_skill_get_subfile_by_name,
112
+ service_skill_update,
111
113
  service_skill_upload,
112
114
  service_skill_upload_sub_file,
113
115
  )
@@ -129,6 +131,17 @@ from .table import (
129
131
  service_update_table_record_by_id,
130
132
  service_update_table_record_by_id_list,
131
133
  )
134
+ from .tag import (
135
+ flatten_tag_tree,
136
+ service_add_entity_tags,
137
+ service_get_tag_detail,
138
+ service_list_entity_tags,
139
+ service_list_entity_tags_by_codes,
140
+ service_list_tags,
141
+ service_remove_entity_tags,
142
+ service_save_entity_tags,
143
+ service_set_entity_tags,
144
+ )
132
145
  from .widget import (
133
146
  service_count_widget_by_code,
134
147
  service_get_widget_data_by_code,
@@ -137,6 +150,14 @@ from .widget import (
137
150
  service_update_widget,
138
151
  servive_tree_widget,
139
152
  )
153
+ from .wiki import (
154
+ service_get_knowledge_base,
155
+ service_list_knowledge_bases,
156
+ service_list_knowledge_documents,
157
+ service_search_knowledge,
158
+ service_search_wiki_pages,
159
+ service_upload_knowledge_file,
160
+ )
140
161
  from .workflow import (
141
162
  service_get_workflow_by_code,
142
163
  service_get_workflow_by_name,
@@ -3,8 +3,8 @@
3
3
  封装技能实体的元数据查询、ZIP 包导入、子文件上传 / 删除以及同步调用:
4
4
 
5
5
  - 列表与详情: ``service_list_skills`` / ``service_get_skill_by_code`` / ``service_get_skill_by_name`` / ``service_list_skill_files``.
6
- - 导入 / 删除: ``service_skill_upload`` / ``service_delete_skill`` / ``service_skill_upload_sub_file`` / ``service_skill_delete_sub_file``.
7
- - 打包 ZIP: ``service_pack_skill_zip``(按允许列表校验源文件夹结构后本地打包为 ZIP).
6
+ - 导入 / 更新 / 删除: ``service_skill_upload`` / ``service_skill_update`` / ``service_delete_skill`` / ``service_skill_upload_sub_file`` / ``service_skill_delete_sub_file``.
7
+ - 打包 / 下载 ZIP: ``service_pack_skill_zip`` / ``service_skill_download``.
8
8
  - 同步调用: ``service_skill_call_by_code``.
9
9
 
10
10
  所有函数均为纯 Python 接口,不依赖 typer/Rich.
@@ -44,7 +44,9 @@ __all__ = [
44
44
  "service_skill_delete_sub_file",
45
45
  "service_get_skill_by_code",
46
46
  "service_get_skill_by_name",
47
+ "service_skill_download",
47
48
  "service_skill_upload",
49
+ "service_skill_update",
48
50
  "service_list_skill_files",
49
51
  "service_list_skills",
50
52
  "service_skill_upload_sub_file",
@@ -314,6 +316,115 @@ def service_skill_upload(
314
316
  return body.get("data") or {}
315
317
 
316
318
 
319
+ def service_skill_update(
320
+ name: str,
321
+ file_path: str | Path,
322
+ *,
323
+ sub_type: MetaSkillSubType | None = None,
324
+ title: str | None = None,
325
+ ) -> dict:
326
+ """全量覆盖更新已有技能(multipart 上传).
327
+
328
+ 按技能业务名解析 ``code`` 后覆盖更新:清空子文件后按 ZIP/文件夹重建。
329
+ 对应后端 ``POST /data/skill/{code}/import``。
330
+
331
+ Args:
332
+ name: 技能业务名.
333
+ file_path: 本地 ZIP 或 .md 文件路径.
334
+ sub_type: 可选技能子类型,``llm`` / ``api`` / ``report``.
335
+ title: 可选覆盖 SKILL.md 中的 ``title`` 字段.
336
+
337
+ Returns:
338
+ 后端返回的 ``data`` 字典.
339
+
340
+ Raises:
341
+ NotFoundError: 找不到对应技能时
342
+ DataOpsError: API 返回错误时
343
+ AuthenticationError: 未认证或认证失败时
344
+ FileNotFoundError: 本地文件不存在时
345
+ """
346
+ path = Path(file_path)
347
+ if not path.exists():
348
+ raise FileNotFoundError(f"文件不存在: {path}")
349
+
350
+ meta = service_get_skill_by_name(name)
351
+ form_data: dict[str, str] = {}
352
+ if sub_type is not None:
353
+ form_data["subType"] = sub_type
354
+ if title:
355
+ form_data["title"] = title
356
+
357
+ with (
358
+ open(path, "rb") as f,
359
+ post_multipart(
360
+ f"/data/skill/{meta.code}/import",
361
+ files={"file": (path.name, f)},
362
+ data=form_data or None,
363
+ ) as resp,
364
+ ):
365
+ body = resp.json()
366
+ return body.get("data") or {}
367
+
368
+
369
+ def service_skill_download(
370
+ name: str,
371
+ output_path: str | Path | None = None,
372
+ ) -> Path:
373
+ """从平台导出技能 ZIP 并保存到本地.
374
+
375
+ 按业务名解析 ``code`` 后调用 ``POST /data/skill/export/{code}``,
376
+ 将返回的 ``application/zip`` 二进制写入本地文件。
377
+
378
+ Args:
379
+ name: 技能业务名.
380
+ output_path: 可选输出路径。省略时写到当前目录 ``{name}.zip``;
381
+ 路径以 ``/`` 或 ``\\`` 结尾时视为目录,在其下生成 ``{name}.zip``;
382
+ 否则视为精确文件路径。
383
+
384
+ Returns:
385
+ 实际写入的 ZIP 文件 :class:`Path` 对象。
386
+
387
+ Raises:
388
+ NotFoundError: 找不到对应技能时
389
+ DataOpsError: API 返回错误时
390
+ AuthenticationError: 未认证或认证失败时
391
+ OSError: 写入本地文件失败时
392
+ """
393
+ meta = service_get_skill_by_name(name)
394
+ try:
395
+ with get_session() as session:
396
+ resp = session.post(f"/data/skill/export/{meta.code}")
397
+ if resp.status_code == 401:
398
+ raise AuthenticationError("认证失败,请先登录")
399
+ if resp.status_code != 200:
400
+ msg = f"HTTP {resp.status_code}"
401
+ try:
402
+ body = resp.json()
403
+ msg = body.get("msg", msg) if isinstance(body, dict) else msg
404
+ except Exception:
405
+ pass
406
+ raise DataOpsError(msg, resp.status_code)
407
+ content = resp.content
408
+ except SystemExit as e:
409
+ raise AuthenticationError("认证失败,请先登录") from e
410
+
411
+ # 默认/目录场景统一用业务名,便于与 upload 对称识别
412
+ zip_filename = f"{name}.zip"
413
+
414
+ if output_path is None:
415
+ out = Path(zip_filename)
416
+ else:
417
+ raw = os.fspath(output_path)
418
+ treat_as_dir = isinstance(raw, str) and raw.endswith(("/", "\\"))
419
+ out = Path(raw)
420
+ if treat_as_dir or out.is_dir():
421
+ out = out / zip_filename
422
+
423
+ out.parent.mkdir(parents=True, exist_ok=True)
424
+ out.write_bytes(content)
425
+ return out
426
+
427
+
317
428
  def service_delete_skill(name: str) -> dict:
318
429
  """按业务名删除技能(级联删除所有 skill_file).
319
430