tinet-agent-cli 0.1.0.dev36__py3-none-any.whl

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 (104) hide show
  1. taco/__init__.py +1 -0
  2. taco/agent_openapi/__init__.py +1 -0
  3. taco/agent_openapi/catalog.py +198 -0
  4. taco/agent_openapi/models.py +47 -0
  5. taco/agent_openapi/parameters.py +111 -0
  6. taco/agent_openapi/service.py +73 -0
  7. taco/aikb/__init__.py +4 -0
  8. taco/aikb/catalog.py +380 -0
  9. taco/aikb/executors.py +157 -0
  10. taco/aikb/file_input.py +55 -0
  11. taco/aikb/models.py +42 -0
  12. taco/aikb/parameters.py +135 -0
  13. taco/aikb/service.py +68 -0
  14. taco/assets/__init__.py +1 -0
  15. taco/assets/agent_openapi/catalog.json +14 -0
  16. taco/assets/agent_openapi/operations/conversation/list-conversations.json +67 -0
  17. taco/assets/agent_openapi/operations/message/list-conversation-messages.json +80 -0
  18. taco/assets/agent_openapi/operations/trace/list-message-traces.json +72 -0
  19. taco/assets/aikb/catalog.json +41 -0
  20. taco/assets/aikb/operations/conversation/chat-conversation-on-open.json +99 -0
  21. taco/assets/aikb/operations/directory/delete-directory.json +81 -0
  22. taco/assets/aikb/operations/directory/edit-directory.json +97 -0
  23. taco/assets/aikb/operations/directory/list-directory-tree.json +106 -0
  24. taco/assets/aikb/operations/directory/save-directory.json +109 -0
  25. taco/assets/aikb/operations/faq/create-faq.json +193 -0
  26. taco/assets/aikb/operations/faq/delete-faq.json +81 -0
  27. taco/assets/aikb/operations/faq/describe-faq.json +82 -0
  28. taco/assets/aikb/operations/faq/edit-faq.json +193 -0
  29. taco/assets/aikb/operations/faq/list-faqs.json +136 -0
  30. taco/assets/aikb/operations/file/create-file.json +145 -0
  31. taco/assets/aikb/operations/file/delete-files.json +110 -0
  32. taco/assets/aikb/operations/file/describe-file.json +82 -0
  33. taco/assets/aikb/operations/file/get-file-upload-url.json +154 -0
  34. taco/assets/aikb/operations/file/list-files.json +146 -0
  35. taco/assets/aikb/operations/media/describe-faq-media-url.json +98 -0
  36. taco/assets/aikb/operations/media/describe-file-media-url.json +90 -0
  37. taco/assets/aikb/operations/oss/signature-for-upload.json +85 -0
  38. taco/assets/aikb/operations/recycle-bin/list-recycled-items.json +151 -0
  39. taco/assets/aikb/operations/repository/describe-bot-repository.json +71 -0
  40. taco/assets/aikb/operations/repository/list-private-repositories.json +75 -0
  41. taco/assets/aikb/operations/repository/list-public-repositories.json +75 -0
  42. taco/assets/aikb/operations/search/search-knowledge-on-open.json +180 -0
  43. taco/assets/examples/README.md +3 -0
  44. taco/assets/examples/agent-basic.json +16 -0
  45. taco/assets/examples/agent-builtin-tool.json +28 -0
  46. taco/assets/examples/agent-workflow-tool.json +30 -0
  47. taco/assets/examples/chatflow-basic.json +24 -0
  48. taco/assets/examples/workflow-http.json +34 -0
  49. taco/assets/manifest.json +12 -0
  50. taco/assets/scenarios/README.md +3 -0
  51. taco/assets/scenarios/agent-basic.json +80 -0
  52. taco/assets/scenarios/agent-builtin-tool.json +116 -0
  53. taco/assets/scenarios/agent-workflow-tool.json +277 -0
  54. taco/assets/schemas/README.md +3 -0
  55. taco/assets/schemas/agent-tool.json +71 -0
  56. taco/assets/schemas/agent.json +199 -0
  57. taco/assets/schemas/chatflow.json +1048 -0
  58. taco/assets/schemas/workflow.http.json +1052 -0
  59. taco/assets/schemas/workflow.json +1052 -0
  60. taco/assets/skills/README.md +3 -0
  61. taco/assets/skills/taco/SKILL.md +68 -0
  62. taco/assets/skills/taco/manifest.json +10 -0
  63. taco/cli.py +127 -0
  64. taco/commands/__init__.py +1 -0
  65. taco/commands/agent.py +760 -0
  66. taco/commands/aikb.py +132 -0
  67. taco/commands/app.py +151 -0
  68. taco/commands/category.py +37 -0
  69. taco/commands/chatflow.py +183 -0
  70. taco/commands/credential.py +222 -0
  71. taco/commands/discovery.py +409 -0
  72. taco/commands/model.py +55 -0
  73. taco/commands/profile.py +124 -0
  74. taco/commands/tool.py +61 -0
  75. taco/commands/workflow.py +714 -0
  76. taco/core/__init__.py +1 -0
  77. taco/core/access_token_manager.py +98 -0
  78. taco/core/api_client.py +263 -0
  79. taco/core/assets.py +81 -0
  80. taco/core/config_store.py +209 -0
  81. taco/core/context.py +19 -0
  82. taco/core/developer_center_client.py +165 -0
  83. taco/core/errors.py +19 -0
  84. taco/core/file_lock.py +80 -0
  85. taco/core/http_headers.py +21 -0
  86. taco/core/openapi_signer.py +221 -0
  87. taco/core/output.py +72 -0
  88. taco/core/profile_manager.py +217 -0
  89. taco/core/profile_resolver.py +151 -0
  90. taco/core/secure_file.py +76 -0
  91. taco/release.py +363 -0
  92. taco/services/__init__.py +1 -0
  93. taco/services/agent_service.py +314 -0
  94. taco/services/app_service.py +153 -0
  95. taco/services/category_service.py +57 -0
  96. taco/services/model_service.py +117 -0
  97. taco/services/tool_service.py +482 -0
  98. taco/services/workflow_compiler.py +1665 -0
  99. taco/services/workflow_service.py +652 -0
  100. taco/services/workflow_tool_service.py +439 -0
  101. tinet_agent_cli-0.1.0.dev36.dist-info/METADATA +158 -0
  102. tinet_agent_cli-0.1.0.dev36.dist-info/RECORD +104 -0
  103. tinet_agent_cli-0.1.0.dev36.dist-info/WHEEL +4 -0
  104. tinet_agent_cli-0.1.0.dev36.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,153 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+ from uuid import UUID
5
+
6
+ from taco.core.api_client import ApiClient
7
+ from taco.core.errors import TacoError
8
+
9
+
10
+ _FINAL_IMPORT_STATUSES = {"completed", "completed-with-warnings"}
11
+
12
+
13
+ class AppService:
14
+ def __init__(self, api_client: ApiClient | None = None) -> None:
15
+ self.api_client = api_client or ApiClient()
16
+
17
+ def list_apps(
18
+ self,
19
+ *,
20
+ page: int = 1,
21
+ limit: int = 20,
22
+ name: str | None = None,
23
+ mode: str | None = None,
24
+ tag_ids: list[str] | None = None,
25
+ profile: str | None = None,
26
+ ) -> Any:
27
+ params: dict[str, Any] = {"page": page, "limit": limit, "compact": True}
28
+ if name:
29
+ params["name"] = name
30
+ if mode:
31
+ params["mode"] = mode
32
+ normalized_tag_ids = _normalize_tag_ids(tag_ids)
33
+ if normalized_tag_ids:
34
+ params["tag_ids"] = ",".join(normalized_tag_ids)
35
+ return self.api_client.get(
36
+ "/apps",
37
+ params=params,
38
+ profile=profile,
39
+ )
40
+
41
+ def list_tags(
42
+ self,
43
+ *,
44
+ keyword: str | None = None,
45
+ profile: str | None = None,
46
+ ) -> Any:
47
+ params = {"type": "app"}
48
+ if keyword:
49
+ params["keyword"] = keyword
50
+ return self.api_client.get(
51
+ "/tags",
52
+ params=params,
53
+ profile=profile,
54
+ )
55
+
56
+ def get_app(self, app_id: str, *, profile: str | None = None) -> Any:
57
+ return self.api_client.get(
58
+ f"/apps/{app_id}",
59
+ profile=profile,
60
+ )
61
+
62
+ def create_app(
63
+ self,
64
+ *,
65
+ name: str,
66
+ mode: str,
67
+ profile: str | None = None,
68
+ ) -> Any:
69
+ return self.api_client.post(
70
+ "/apps",
71
+ json={"name": name, "mode": mode},
72
+ profile=profile,
73
+ )
74
+
75
+ def list_templates(
76
+ self,
77
+ *,
78
+ language: str | None = None,
79
+ profile: str | None = None,
80
+ ) -> Any:
81
+ params = {"language": language} if language else None
82
+ return self.api_client.get(
83
+ "/explore/apps",
84
+ params=params,
85
+ profile=profile,
86
+ )
87
+
88
+ def create_app_from_template(
89
+ self,
90
+ template_app_id: str,
91
+ *,
92
+ name: str | None = None,
93
+ profile: str | None = None,
94
+ ) -> Any:
95
+ detail = self.api_client.get(
96
+ f"/explore/apps/{template_app_id}",
97
+ profile=profile,
98
+ )
99
+ export_data = detail.get("export_data") if isinstance(detail, dict) else None
100
+ if not isinstance(export_data, str) or not export_data.strip():
101
+ raise TacoError(
102
+ code="APP_TEMPLATE_DETAIL_INVALID",
103
+ message="应用模板详情缺少有效 export_data。",
104
+ exit_code=4,
105
+ hint="请重新获取模板列表并确认模板应用 ID。",
106
+ )
107
+
108
+ payload = {"mode": "yaml-content", "yaml_content": export_data}
109
+ if name:
110
+ payload["name"] = name
111
+ result = self.api_client.post(
112
+ "/apps/imports",
113
+ json=payload,
114
+ profile=profile,
115
+ )
116
+ status = result.get("status") if isinstance(result, dict) else None
117
+ if status == "pending":
118
+ import_id = result.get("id")
119
+ if not isinstance(import_id, str) or not import_id.strip():
120
+ raise _invalid_template_import_response()
121
+ result = self.api_client.post(
122
+ f"/apps/imports/{import_id}/confirm",
123
+ profile=profile,
124
+ )
125
+ status = result.get("status") if isinstance(result, dict) else None
126
+
127
+ if status not in _FINAL_IMPORT_STATUSES:
128
+ raise _invalid_template_import_response()
129
+ return result
130
+
131
+
132
+ def _normalize_tag_ids(tag_ids: list[str] | None) -> list[str]:
133
+ normalized = []
134
+ for tag_id in tag_ids or []:
135
+ try:
136
+ normalized.append(str(UUID(tag_id.strip())))
137
+ except (AttributeError, ValueError):
138
+ raise TacoError(
139
+ code="APP_LIST_TAG_ID_INVALID",
140
+ message=f"标签 ID 不是有效的 UUID:{tag_id}",
141
+ exit_code=2,
142
+ hint="请通过 --tag-id 传入有效的标签 UUID。",
143
+ ) from None
144
+ return normalized
145
+
146
+
147
+ def _invalid_template_import_response() -> TacoError:
148
+ return TacoError(
149
+ code="APP_TEMPLATE_IMPORT_RESPONSE_INVALID",
150
+ message="应用模板导入响应缺少有效的完成状态。",
151
+ exit_code=4,
152
+ hint="请检查模板兼容性和 Console API 响应。",
153
+ )
@@ -0,0 +1,57 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from taco.core.api_client import ApiClient
6
+ from taco.core.errors import TacoError
7
+
8
+
9
+ class CategoryService:
10
+ def __init__(self, api_client: ApiClient | None = None) -> None:
11
+ self.api_client = api_client or ApiClient()
12
+
13
+ def list_categories(self, *, profile: str | None = None) -> list[dict[str, Any]]:
14
+ payload = self.api_client.get("/tinet/app/categories", profile=profile)
15
+ if not isinstance(payload, list) or any(
16
+ not isinstance(item, dict) for item in payload
17
+ ):
18
+ raise TacoError(
19
+ code="CATEGORY_RESPONSE_INVALID",
20
+ message="分类接口返回结构不合法。",
21
+ exit_code=4,
22
+ )
23
+ return payload
24
+
25
+ def get_category(
26
+ self,
27
+ code: str,
28
+ *,
29
+ profile: str | None = None,
30
+ ) -> dict[str, Any]:
31
+ category = _find_category(self.list_categories(profile=profile), code)
32
+ if category is None:
33
+ raise TacoError(
34
+ code="CATEGORY_NOT_FOUND",
35
+ message=f"未找到智能体分类:{code}",
36
+ exit_code=6,
37
+ hint="请先执行 taco category list,不要猜测分类 code。",
38
+ )
39
+ return category
40
+
41
+
42
+ def _find_category(
43
+ categories: list[dict[str, Any]],
44
+ code: str,
45
+ ) -> dict[str, Any] | None:
46
+ for category in categories:
47
+ if category.get("code") == code:
48
+ return category
49
+ children = category.get("children")
50
+ if isinstance(children, list):
51
+ child = _find_category(
52
+ [item for item in children if isinstance(item, dict)],
53
+ code,
54
+ )
55
+ if child is not None:
56
+ return child
57
+ return None
@@ -0,0 +1,117 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+ from urllib.parse import quote
5
+
6
+ from taco.core.api_client import ApiClient
7
+ from taco.core.errors import TacoError
8
+ from taco.services.category_service import CategoryService
9
+
10
+
11
+ class ModelService:
12
+ def __init__(
13
+ self,
14
+ api_client: ApiClient | None = None,
15
+ *,
16
+ category_service: CategoryService | None = None,
17
+ ) -> None:
18
+ self.api_client = api_client or ApiClient()
19
+ self.category_service = category_service or CategoryService(
20
+ api_client=self.api_client
21
+ )
22
+
23
+ def list_models(
24
+ self,
25
+ *,
26
+ category: str | None = None,
27
+ profile: str | None = None,
28
+ ) -> dict[str, Any]:
29
+ if category is not None:
30
+ self.category_service.get_category(category, profile=profile)
31
+ payload = self.api_client.get(
32
+ "/workspaces/current/models/model-types/llm",
33
+ profile=profile,
34
+ )
35
+ providers = payload.get("data") if isinstance(payload, dict) else None
36
+ if not isinstance(providers, list):
37
+ raise _invalid_model_response()
38
+
39
+ items: list[dict[str, Any]] = []
40
+ for provider in providers:
41
+ if not isinstance(provider, dict):
42
+ raise _invalid_model_response()
43
+ provider_id = provider.get("provider")
44
+ models = provider.get("models")
45
+ if not isinstance(provider_id, str) or not isinstance(models, list):
46
+ continue
47
+ for model in models:
48
+ if not isinstance(model, dict) or not isinstance(
49
+ model.get("model"),
50
+ str,
51
+ ):
52
+ continue
53
+ categories = model.get("t_categories")
54
+ if (
55
+ category
56
+ and isinstance(categories, list)
57
+ and category not in categories
58
+ ):
59
+ continue
60
+ items.append(
61
+ {
62
+ **model,
63
+ "provider": provider_id,
64
+ "provider_label": provider.get("label"),
65
+ }
66
+ )
67
+ return {"category": category, "items": items}
68
+
69
+ def describe_model(
70
+ self,
71
+ *,
72
+ provider: str,
73
+ model: str,
74
+ category: str | None = None,
75
+ profile: str | None = None,
76
+ ) -> dict[str, Any]:
77
+ models = self.list_models(category=category, profile=profile)["items"]
78
+ item = next(
79
+ (
80
+ candidate
81
+ for candidate in models
82
+ if candidate.get("provider") == provider
83
+ and candidate.get("model") == model
84
+ ),
85
+ None,
86
+ )
87
+ if item is None:
88
+ raise TacoError(
89
+ code="MODEL_NOT_FOUND",
90
+ message=f"未找到分类可用模型:{provider}/{model}",
91
+ exit_code=6,
92
+ hint="请先执行 taco model list --category <code>。",
93
+ )
94
+ rules_payload = self.api_client.get(
95
+ (
96
+ "/workspaces/current/model-providers/"
97
+ f"{quote(provider, safe='')}/models/parameter-rules"
98
+ ),
99
+ params={"model": model},
100
+ profile=profile,
101
+ )
102
+ rules = (
103
+ rules_payload.get("data")
104
+ if isinstance(rules_payload, dict)
105
+ else None
106
+ )
107
+ if not isinstance(rules, list):
108
+ raise _invalid_model_response()
109
+ return {**item, "parameter_rules": rules}
110
+
111
+
112
+ def _invalid_model_response() -> TacoError:
113
+ return TacoError(
114
+ code="MODEL_RESPONSE_INVALID",
115
+ message="模型接口返回结构不合法。",
116
+ exit_code=4,
117
+ )