glaip-sdk 0.5.3__py3-none-any.whl → 0.6.0__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 (39) hide show
  1. glaip_sdk/__init__.py +4 -1
  2. glaip_sdk/agents/__init__.py +27 -0
  3. glaip_sdk/agents/base.py +989 -0
  4. glaip_sdk/cli/commands/accounts.py +210 -23
  5. glaip_sdk/cli/commands/tools.py +2 -5
  6. glaip_sdk/client/_agent_payloads.py +10 -9
  7. glaip_sdk/client/agents.py +70 -8
  8. glaip_sdk/client/base.py +1 -0
  9. glaip_sdk/client/main.py +12 -4
  10. glaip_sdk/client/mcps.py +112 -10
  11. glaip_sdk/client/tools.py +151 -7
  12. glaip_sdk/mcps/__init__.py +21 -0
  13. glaip_sdk/mcps/base.py +345 -0
  14. glaip_sdk/models/__init__.py +65 -31
  15. glaip_sdk/models/agent.py +47 -0
  16. glaip_sdk/models/agent_runs.py +0 -1
  17. glaip_sdk/models/common.py +42 -0
  18. glaip_sdk/models/mcp.py +33 -0
  19. glaip_sdk/models/tool.py +33 -0
  20. glaip_sdk/registry/__init__.py +55 -0
  21. glaip_sdk/registry/agent.py +164 -0
  22. glaip_sdk/registry/base.py +139 -0
  23. glaip_sdk/registry/mcp.py +251 -0
  24. glaip_sdk/registry/tool.py +238 -0
  25. glaip_sdk/tools/__init__.py +22 -0
  26. glaip_sdk/tools/base.py +435 -0
  27. glaip_sdk/utils/__init__.py +50 -9
  28. glaip_sdk/utils/bundler.py +267 -0
  29. glaip_sdk/utils/client.py +111 -0
  30. glaip_sdk/utils/client_utils.py +26 -7
  31. glaip_sdk/utils/discovery.py +78 -0
  32. glaip_sdk/utils/import_resolver.py +500 -0
  33. glaip_sdk/utils/instructions.py +101 -0
  34. glaip_sdk/utils/sync.py +142 -0
  35. {glaip_sdk-0.5.3.dist-info → glaip_sdk-0.6.0.dist-info}/METADATA +5 -3
  36. {glaip_sdk-0.5.3.dist-info → glaip_sdk-0.6.0.dist-info}/RECORD +38 -18
  37. glaip_sdk/models.py +0 -241
  38. {glaip_sdk-0.5.3.dist-info → glaip_sdk-0.6.0.dist-info}/WHEEL +0 -0
  39. {glaip_sdk-0.5.3.dist-info → glaip_sdk-0.6.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,142 @@
1
+ """Agent and tool synchronization (create/update) operations.
2
+
3
+ This module provides convenience functions for tool classes that need bundling.
4
+
5
+ For direct upsert operations, use the client methods:
6
+ - client.agents.upsert_agent(identifier, **kwargs)
7
+ - client.tools.upsert_tool(identifier, code, **kwargs)
8
+ - client.mcps.upsert_mcp(identifier, **kwargs)
9
+
10
+ Authors:
11
+ Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from typing import TYPE_CHECKING, Any
17
+
18
+ from glaip_sdk.utils.bundler import ToolBundler
19
+ from glaip_sdk.utils.import_resolver import load_class
20
+ from gllm_core.utils import LoggerManager
21
+
22
+ if TYPE_CHECKING:
23
+ from glaip_sdk.models import Agent, Tool
24
+
25
+ logger = LoggerManager().get_logger(__name__)
26
+
27
+
28
+ def _extract_tool_name(tool_class: Any) -> str:
29
+ """Extract tool name from a class, handling Pydantic v2 models."""
30
+ # Direct attribute access (works for non-Pydantic classes)
31
+ if hasattr(tool_class, "name"):
32
+ name = getattr(tool_class, "name", None)
33
+ if isinstance(name, str):
34
+ return name
35
+
36
+ # Pydantic v2 model - check model_fields
37
+ if hasattr(tool_class, "model_fields"):
38
+ model_fields = getattr(tool_class, "model_fields", {})
39
+ if "name" in model_fields:
40
+ field_info = model_fields["name"]
41
+ if hasattr(field_info, "default") and isinstance(field_info.default, str):
42
+ return field_info.default
43
+
44
+ raise ValueError(f"Cannot extract name from tool class: {tool_class}")
45
+
46
+
47
+ def _extract_tool_description(tool_class: Any) -> str:
48
+ """Extract tool description from a class, handling Pydantic v2 models."""
49
+ # Direct attribute access
50
+ if hasattr(tool_class, "description"):
51
+ desc = getattr(tool_class, "description", None)
52
+ if isinstance(desc, str):
53
+ return desc
54
+
55
+ # Pydantic v2 model - check model_fields
56
+ if hasattr(tool_class, "model_fields"):
57
+ model_fields = getattr(tool_class, "model_fields", {})
58
+ if "description" in model_fields:
59
+ field_info = model_fields["description"]
60
+ if hasattr(field_info, "default") and isinstance(field_info.default, str):
61
+ return field_info.default
62
+
63
+ return ""
64
+
65
+
66
+ def update_or_create_tool(tool_ref: Any) -> Tool:
67
+ """Create or update a tool from a tool class with bundled source code.
68
+
69
+ This function takes a tool class (LangChain BaseTool), bundles its source
70
+ code with inlined imports, and creates/updates it in the backend.
71
+
72
+ Args:
73
+ tool_ref: A tool class (LangChain BaseTool subclass) or import path string.
74
+
75
+ Returns:
76
+ The created or updated tool.
77
+
78
+ Example:
79
+ >>> from glaip_sdk.utils.sync import update_or_create_tool
80
+ >>> from my_tools import WeatherAPITool
81
+ >>> tool = update_or_create_tool(WeatherAPITool)
82
+ """
83
+ from glaip_sdk.utils.client import get_client # noqa: PLC0415
84
+
85
+ client = get_client()
86
+
87
+ # Handle string import path
88
+ if isinstance(tool_ref, str):
89
+ tool_class = load_class(tool_ref)
90
+ else:
91
+ tool_class = tool_ref
92
+
93
+ # Get tool info - handle Pydantic v2 model classes
94
+ tool_name = _extract_tool_name(tool_class)
95
+ tool_description = _extract_tool_description(tool_class)
96
+
97
+ # Bundle source code
98
+ bundler = ToolBundler(tool_class)
99
+ bundled_source = bundler.bundle()
100
+
101
+ logger.info("Tool info: name='%s', description='%s...'", tool_name, tool_description[:50])
102
+ logger.info("Bundled source code: %d characters", len(bundled_source))
103
+
104
+ # Use client's upsert method
105
+ return client.tools.upsert_tool(
106
+ tool_name,
107
+ code=bundled_source,
108
+ description=tool_description,
109
+ )
110
+
111
+
112
+ def update_or_create_agent(agent_config: dict[str, Any]) -> Agent:
113
+ """Create or update an agent from configuration.
114
+
115
+ Args:
116
+ agent_config: Agent configuration dictionary containing:
117
+ - name (str): Agent name (required)
118
+ - description (str): Agent description
119
+ - instruction (str): Agent instruction
120
+ - tools (list, optional): List of tool IDs
121
+ - agents (list, optional): List of sub-agent IDs
122
+ - metadata (dict, optional): Additional metadata
123
+
124
+ Returns:
125
+ The created or updated agent.
126
+
127
+ Example:
128
+ >>> from glaip_sdk.utils.sync import update_or_create_agent
129
+ >>> config = {
130
+ ... "name": "weather_reporter",
131
+ ... "description": "Weather reporting agent",
132
+ ... "instruction": "You are a weather reporter.",
133
+ ... }
134
+ >>> agent = update_or_create_agent(config)
135
+ """
136
+ from glaip_sdk.utils.client import get_client # noqa: PLC0415
137
+
138
+ client = get_client()
139
+ agent_name = agent_config.pop("name")
140
+
141
+ # Use client's upsert method
142
+ return client.agents.upsert_agent(agent_name, **agent_config)
@@ -1,18 +1,20 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: glaip-sdk
3
- Version: 0.5.3
3
+ Version: 0.6.0
4
4
  Summary: Python SDK for GL AIP (GDP Labs AI Agent Package) - Simplified CLI Design
5
5
  License: MIT
6
6
  Author: Raymond Christopher
7
7
  Author-email: raymond.christopher@gdplabs.id
8
- Requires-Python: >=3.10,<4.0
8
+ Requires-Python: >=3.11,<3.14
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.10
12
11
  Classifier: Programming Language :: Python :: 3.11
13
12
  Classifier: Programming Language :: Python :: 3.12
14
13
  Requires-Dist: click (>=8.2.0,<8.3.0)
14
+ Requires-Dist: gllm-core-binary (>=0.1.0)
15
+ Requires-Dist: gllm-tools-binary (>=0.1.3)
15
16
  Requires-Dist: httpx (>=0.28.1)
17
+ Requires-Dist: langchain-core (>=0.3.0)
16
18
  Requires-Dist: packaging (>=23.2)
17
19
  Requires-Dist: pydantic (>=2.0.0)
18
20
  Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
@@ -1,18 +1,20 @@
1
- glaip_sdk/__init__.py,sha256=7ICOkPeiwQGkadqxIgJXOYPHcJOHYRIF_GU0xkjOtSE,366
1
+ glaip_sdk/__init__.py,sha256=0PAFfodqAEdggIiV1Es_JryDokZrhYLFFIXosqdguJU,420
2
2
  glaip_sdk/_version.py,sha256=5CHGCxx_36fgmMWuEx6jJ2CzzM-i9eBFyQWFwBi23XE,2259
3
+ glaip_sdk/agents/__init__.py,sha256=VfYov56edbWuySXFEbWJ_jLXgwnFzPk1KB-9-mfsUCc,776
4
+ glaip_sdk/agents/base.py,sha256=PLl1B8guGxNLeDvObrgCP-Lk12lFrwFMcK-mJl9rjrk,33577
3
5
  glaip_sdk/branding.py,sha256=tLqYCIHMkUf8p2smpuAGNptwaKUN38G4mlh0A0DOl_w,7823
4
6
  glaip_sdk/cli/__init__.py,sha256=xCCfuF1Yc7mpCDcfhHZTX0vizvtrDSLeT8MJ3V7m5A0,156
5
7
  glaip_sdk/cli/account_store.py,sha256=NXuAVPaJS_32Aw1VTaZCNwIID-gADw4F_UMieoWmg3g,17336
6
8
  glaip_sdk/cli/agent_config.py,sha256=YAbFKrTNTRqNA6b0i0Q3pH-01rhHDRi5v8dxSFwGSwM,2401
7
9
  glaip_sdk/cli/auth.py,sha256=9hfjZyd4cx2_mImqykJ1sWQsuVTR2gy6D4hFqAQNKL4,24129
8
10
  glaip_sdk/cli/commands/__init__.py,sha256=6Z3ASXDut0lAbUX_umBFtxPzzFyqoiZfVeTahThFu1A,219
9
- glaip_sdk/cli/commands/accounts.py,sha256=B5itsUzqoH_hBRYOVd2m4nPoIuBbPDIoK974zKMm9NE,18635
11
+ glaip_sdk/cli/commands/accounts.py,sha256=NTexdyiv9Qp3xZMxmtwOWeCkRDHegyk06O9J3UWyXHQ,24644
10
12
  glaip_sdk/cli/commands/agents.py,sha256=WCOzllyh_Znwlju5camT4vE6OeRJbsAmjWwcyiAqWs4,48429
11
13
  glaip_sdk/cli/commands/common_config.py,sha256=IY13gPkeifXxSdpzRFUvfRin8J7s38p6Y7TYjdGw7w4,2474
12
14
  glaip_sdk/cli/commands/configure.py,sha256=95PQiJnpvsdH02v_tLVANd64qAJJnZKlhNe4tpfWIS4,30262
13
15
  glaip_sdk/cli/commands/mcps.py,sha256=tttqQnfM89iI9Pm94u8YRhiHMQNYNouecFX0brsT4cQ,42551
14
16
  glaip_sdk/cli/commands/models.py,sha256=vfcGprK5CHprQ0CNpNzQlNNTELvdgKC7JxTG_ijOwmE,2009
15
- glaip_sdk/cli/commands/tools.py,sha256=7_RMTuTI1Guu7psClovbyt2umfk4rkp7jSW19GXKA44,18440
17
+ glaip_sdk/cli/commands/tools.py,sha256=_VBqG-vIjnn-gqvDlSTvcU7_F4N3ANGGKEECcQVR-BM,18430
16
18
  glaip_sdk/cli/commands/transcripts.py,sha256=ofxZLus1xLB061NxrLo1J6LPEb2VIxJTjmz7hLKgPmc,26377
17
19
  glaip_sdk/cli/commands/update.py,sha256=rIZo_x-tvpvcwpQLpwYwso1ix6qTHuNNTL4egmn5fEM,1812
18
20
  glaip_sdk/cli/config.py,sha256=_UU7pljAhgzwKLx7Yqp2_ibiInR-dHuykC_UWL51BHc,2310
@@ -47,33 +49,50 @@ glaip_sdk/cli/update_notifier.py,sha256=FnTjzS8YT94RmP6c5aU_XNIyRi7FRHvAskMy-VJi
47
49
  glaip_sdk/cli/utils.py,sha256=fV6PZlQ7K5zckpFWvwh3yLmETGrVylK9AXtN7zKBp-A,57374
48
50
  glaip_sdk/cli/validators.py,sha256=d-kq4y7HWMo6Gc7wLXWUsCt8JwFvJX_roZqRm1Nko1I,5622
49
51
  glaip_sdk/client/__init__.py,sha256=F-eE_dRSzA0cc1it06oi0tZetZBHmSUjWSHGhJMLCls,263
50
- glaip_sdk/client/_agent_payloads.py,sha256=VfBHoijuoqUOixGBf2SA2vlQIXQmBsjB3sXHZhXYiec,17681
52
+ glaip_sdk/client/_agent_payloads.py,sha256=cH7CvNRn0JvudwKLr072E7W2QGWO9r-4xDxWMvXoPKE,17865
51
53
  glaip_sdk/client/agent_runs.py,sha256=tZSFEZZ3Yx0uYRgnwkLe-X0TlmgKJQ-ivzb6SrVnxY8,4862
52
- glaip_sdk/client/agents.py,sha256=tKIjkU9-lMEehf1lJe8Bl35nNQntIiyvq02b4fsVN5c,43332
53
- glaip_sdk/client/base.py,sha256=ikW33raz2M6rXzo3JmhttfXXuVdMv5zBRKEZkU1F-4I,18176
54
- glaip_sdk/client/main.py,sha256=-grOD3mMNbjOPbx2s1ZIF0z0KpEaCaNuXLHX9dqcZgQ,8711
55
- glaip_sdk/client/mcps.py,sha256=410HY1aC8hzaCDnEGnhrhKs8vC2xQ50PHvUy1PuuIIc,9364
54
+ glaip_sdk/client/agents.py,sha256=QSeXH93ysyNae67FCStIpDfDr33t4_d2gXpJD07GV54,45866
55
+ glaip_sdk/client/base.py,sha256=BhNaC2TJJ2jVWRTYmfxD3WjYgAyIuWNz9YURdNXXjJo,18245
56
+ glaip_sdk/client/main.py,sha256=CRan8BCTH84d7MwJ-unAkpRlT5_oJkPnz9M7qe-fAl0,9034
57
+ glaip_sdk/client/mcps.py,sha256=gFRuLOGeh6ieIhR4PeD6yNVT6NhvUMTqPq9iuu1vkAY,13019
56
58
  glaip_sdk/client/run_rendering.py,sha256=ubBO-NzyZoYRELNwxVvrQFRGQVJCuLfqqJNiXrBZDoQ,14223
57
59
  glaip_sdk/client/shared.py,sha256=esHlsR0LEfL-pFDaWebQjKKOLl09jsRY-2pllBUn4nU,522
58
- glaip_sdk/client/tools.py,sha256=LP7ZRMMlaolBpsu6M14KUifiCM2MWrQoWwX_DYgNxhE,17293
60
+ glaip_sdk/client/tools.py,sha256=RR7345wECqPtofDXPW12VOnLtus554tXleL0YHQy82U,22435
59
61
  glaip_sdk/client/validators.py,sha256=ioF9VCs-LG2yLkaRDd7Hff74lojDZZ0_Q3CiLbdm1RY,8381
60
62
  glaip_sdk/config/constants.py,sha256=Y03c6op0e7K0jTQ8bmWXhWAqsnjWxkAhWniq8Z0iEKY,1081
61
63
  glaip_sdk/exceptions.py,sha256=iAChFClkytXRBLP0vZq1_YjoZxA9i4m4bW1gDLiGR1g,2321
62
64
  glaip_sdk/icons.py,sha256=J5THz0ReAmDwIiIooh1_G3Le-mwTJyEjhJDdJ13KRxM,524
63
- glaip_sdk/models/__init__.py,sha256=DtFft8zH3eJjeedm6jov1z54wTLTcb6dyOKRwM9ZGbk,1756
64
- glaip_sdk/models/agent_runs.py,sha256=oGUxS4UOq8C2QE4ilp0IQZ7ur1m0DPh6ybzTAOg2tcc,3808
65
- glaip_sdk/models.py,sha256=OyaGkh1OoWJeVAbIjnkPC8XhtuxJ7aylDvwsKC8LPqs,8504
65
+ glaip_sdk/mcps/__init__.py,sha256=4jYrt8K__oxrxexHRcmnRBXt-W_tbJN61H9Kf2lVh4Q,551
66
+ glaip_sdk/mcps/base.py,sha256=jWwHjDF67_mtDGRp9p5SolANjVeB8jt1PSwPBtX876M,11654
67
+ glaip_sdk/models/__init__.py,sha256=-qO4Yr1-fkyaYC9RcT3nYhplDjoXATrIFZr4JrqflHI,2577
68
+ glaip_sdk/models/agent.py,sha256=vtmUSDrrib1hvm0xnofIuOebqlrs-gIaLsny8hzg1iE,1523
69
+ glaip_sdk/models/agent_runs.py,sha256=MYgab07k8MfExjvI5_o6HxsksJZ3tl2TDZefVxzGc1g,3807
70
+ glaip_sdk/models/common.py,sha256=O30MEGO2nKcGhKbnPNkoGzwNvDVUBjM-uU-Tpigaz5Y,1180
71
+ glaip_sdk/models/mcp.py,sha256=ti_8MUf4k7qbR1gPs9JhqhybMcLUhZxEELtHQrTv2-U,944
72
+ glaip_sdk/models/tool.py,sha256=w3nL2DqyCtGgDPCd40Asi9obRGghQjLlC9Vt_p32Mpc,951
66
73
  glaip_sdk/payload_schemas/__init__.py,sha256=nTJmzwn2BbEpzZdq-8U24eVHQHxqYO3_-SABMV9lS_Q,142
67
74
  glaip_sdk/payload_schemas/agent.py,sha256=Nap68mI2Ba8eNGOhk79mGrYUoYUahcUJLof3DLWtVO4,3198
75
+ glaip_sdk/registry/__init__.py,sha256=5y4zDT0fNnti0yhd2gv9f8rppgq9Cx6dyFaTV1tL3hc,1647
76
+ glaip_sdk/registry/agent.py,sha256=F0axW4BIUODqnttIOzxnoS5AqQkLZ1i48FTeZNnYkhA,5203
77
+ glaip_sdk/registry/base.py,sha256=e3KUD7WuKypvbu_h-roouD-ynIp49nDZavgpbgSdPbk,4151
78
+ glaip_sdk/registry/mcp.py,sha256=bCpO-2ybaeQyKIQfdmz6BKmdPYb-_MG9jYEJNFykpQg,7764
79
+ glaip_sdk/registry/tool.py,sha256=Y3mubiT84TOGByxOab1gF5ROBzcak_6o__JEGiv7uyM,7871
68
80
  glaip_sdk/rich_components.py,sha256=44Z0V1ZQleVh9gUDGwRR5mriiYFnVGOhm7fFxZYbP8c,4052
69
- glaip_sdk/utils/__init__.py,sha256=Fy11SCrasMRNnP-qbZ-Rr9JMhxgHHcSGG2v7jd7PP20,1087
81
+ glaip_sdk/tools/__init__.py,sha256=rhGzEqQFCzeMrxmikBuNrMz4PyYczwic28boDKVmoHs,585
82
+ glaip_sdk/tools/base.py,sha256=bvumLJ-DiQTmuYKgq2yCnlwrTZ9nYXpOwWU0e1vWR5g,15185
83
+ glaip_sdk/utils/__init__.py,sha256=cAvQ3V0nocJxAOJ3_cablcGAsZkWzypDf9bm_cfM1dg,2750
70
84
  glaip_sdk/utils/agent_config.py,sha256=RhcHsSOVwOaSC2ggnPuHn36Aa0keGJhs8KGb2InvzRk,7262
71
- glaip_sdk/utils/client_utils.py,sha256=huMq2FWS4YnTTjWT23gaZABVdqRGRFLpcyhnQR8bs2c,14328
85
+ glaip_sdk/utils/bundler.py,sha256=fQWAv0e5qNjF1Lah-FGoA9W5Q59YaHbQfX_4ZB84YRw,9120
86
+ glaip_sdk/utils/client.py,sha256=otPUOIDvLCCsvFBNR8YMZFtRrORggmvvlFjl3YeeTqQ,3121
87
+ glaip_sdk/utils/client_utils.py,sha256=hzHxxNuM37mK4HhgIdS0qg4AqjAA5ai2irPO6Nr1Uzo,15350
72
88
  glaip_sdk/utils/datetime_helpers.py,sha256=QLknNLEAY56628-MTRKnCXAffATkF33erOqBubKmU98,1544
89
+ glaip_sdk/utils/discovery.py,sha256=DbnPuCXuS5mwTZ9fMfsPHQDJltFV99Wf8Em0YttktVU,1994
73
90
  glaip_sdk/utils/display.py,sha256=zu3SYqxj9hPyEN8G1vIXv_yXBkV8jLLCXEg2rs8NlzM,4485
74
91
  glaip_sdk/utils/export.py,sha256=1NxxE3wGsA1auzecG5oJw5ELB4VmPljoeIkGhrGOh1I,5006
75
92
  glaip_sdk/utils/general.py,sha256=3HSVIopUsIymPaim-kP2lqLX75TkkdIVLe6g3UKabZ0,1507
76
93
  glaip_sdk/utils/import_export.py,sha256=RCvoydm_6_L7_J1igcE6IYDunqgS5mQUbWT4VGrytMw,5510
94
+ glaip_sdk/utils/import_resolver.py,sha256=PAM9-3KgxVJD4TO0qsf7vocI1OTpQ6GjUEvtInBTvVQ,16560
95
+ glaip_sdk/utils/instructions.py,sha256=MTk93lsq3I8aRnvnRMSXXNMzcpnaIM_Pm3Aiiiq3GBc,2997
77
96
  glaip_sdk/utils/rendering/__init__.py,sha256=cJhhBEf46RnmUGJ1fivGkFuCoOn2pkJkSuRWoo1xlhE,3608
78
97
  glaip_sdk/utils/rendering/formatting.py,sha256=tP-CKkKFDhiAHS1vpJQ3D6NmPVl0TX1ZOwBOoxia2eE,8009
79
98
  glaip_sdk/utils/rendering/layout/__init__.py,sha256=Lz8eLXDO28wyK36BhKJ6o9YmsRjmQZrNhvZ2wwSjvPw,1609
@@ -106,8 +125,9 @@ glaip_sdk/utils/rendering/viewer/presenter.py,sha256=mlLMTjnyeyPVtsyrAbz1BJu9lFG
106
125
  glaip_sdk/utils/resource_refs.py,sha256=vF34kyAtFBLnaKnQVrsr2st1JiSxVbIZ4yq0DelJvCI,5966
107
126
  glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
108
127
  glaip_sdk/utils/serialization.py,sha256=z-qpvWLSBrGK3wbUclcA1UIKLXJedTnMSwPdq-FF4lo,13308
128
+ glaip_sdk/utils/sync.py,sha256=3VKqs1UfNGWSobgRXohBKP7mMMzdUW3SU0bJQ1uxOgw,4872
109
129
  glaip_sdk/utils/validation.py,sha256=Vt8oSnn7OM6ns5vjOl5FwGIMWBPb0yI6RD5XL_L5_4M,6826
110
- glaip_sdk-0.5.3.dist-info/METADATA,sha256=RwJBNhUEnTWDIPr-X4oYiLk-8GtG2IzBoV41jxGkad0,7053
111
- glaip_sdk-0.5.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
112
- glaip_sdk-0.5.3.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
113
- glaip_sdk-0.5.3.dist-info/RECORD,,
130
+ glaip_sdk-0.6.0.dist-info/METADATA,sha256=kFvWJW0jzG-EdvGTRJoaZBaXqDNk66EpZN_Q9tq0OUM,7128
131
+ glaip_sdk-0.6.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
132
+ glaip_sdk-0.6.0.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
133
+ glaip_sdk-0.6.0.dist-info/RECORD,,
glaip_sdk/models.py DELETED
@@ -1,241 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Data models for AIP SDK.
3
-
4
- Authors:
5
- Raymond Christopher (raymond.christopher@gdplabs.id)
6
- """
7
-
8
- from collections.abc import AsyncGenerator
9
- from datetime import datetime
10
- from typing import Any
11
-
12
- from pydantic import BaseModel
13
-
14
- from glaip_sdk.config.constants import DEFAULT_AGENT_RUN_TIMEOUT
15
-
16
- _AGENT_CLIENT_REQUIRED_MSG = "No client available. Use client.get_agent_by_id() to get a client-connected agent."
17
- _MCP_CLIENT_REQUIRED_MSG = "No client available. Use client.get_mcp_by_id() to get a client-connected MCP."
18
-
19
-
20
- class Agent(BaseModel):
21
- """Agent model for API responses."""
22
-
23
- id: str
24
- name: str
25
- instruction: str | None = None
26
- description: str | None = None
27
- type: str | None = None
28
- framework: str | None = None
29
- version: str | None = None
30
- tools: list[dict[str, Any]] | None = None
31
- agents: list[dict[str, Any]] | None = None
32
- mcps: list[dict[str, Any]] | None = None
33
- tool_configs: dict[str, Any] | None = None
34
- mcp_configs: dict[str, Any] | None = None
35
- agent_config: dict[str, Any] | None = None
36
- timeout: int = DEFAULT_AGENT_RUN_TIMEOUT
37
- metadata: dict[str, Any] | None = None
38
- language_model_id: str | None = None
39
- a2a_profile: dict[str, Any] | None = None
40
- created_at: datetime | None = None
41
- updated_at: datetime | None = None
42
- _client: Any = None
43
-
44
- def _set_client(self, client: Any) -> "Agent":
45
- """Set the client reference for this resource."""
46
- self._client = client
47
- return self
48
-
49
- def run(self, message: str, verbose: bool = False, **kwargs) -> str:
50
- """Run the agent with a message.
51
-
52
- Args:
53
- message: The message to send to the agent
54
- verbose: Enable verbose output and event JSON logging
55
- **kwargs: Additional arguments passed to run_agent
56
- """
57
- if not self._client:
58
- raise RuntimeError(_AGENT_CLIENT_REQUIRED_MSG)
59
- # Automatically pass the agent name for better renderer display
60
- kwargs.setdefault("agent_name", self.name)
61
- # Pass the agent's configured timeout if not explicitly overridden
62
- if "timeout" not in kwargs:
63
- kwargs["timeout"] = self.timeout
64
- # Pass verbose flag through to enable event JSON output
65
- return self._client.run_agent(self.id, message, verbose=verbose, **kwargs)
66
-
67
- async def arun(self, message: str, **kwargs) -> AsyncGenerator[dict, None]:
68
- """Async run the agent with a message, yielding streaming JSON chunks.
69
-
70
- Args:
71
- message: The message to send to the agent
72
- **kwargs: Additional arguments passed to arun_agent
73
-
74
- Yields:
75
- Dictionary containing parsed JSON chunks from the streaming response
76
-
77
- Raises:
78
- RuntimeError: When no client is available
79
- AgentTimeoutError: When agent execution times out
80
- Exception: For other unexpected errors
81
- """
82
- if not self._client:
83
- raise RuntimeError(_AGENT_CLIENT_REQUIRED_MSG)
84
- # Automatically pass the agent name for better context
85
- kwargs.setdefault("agent_name", self.name)
86
- # Pass the agent's configured timeout if not explicitly overridden
87
- if "timeout" not in kwargs:
88
- kwargs["timeout"] = self.timeout
89
-
90
- async for chunk in self._client.arun_agent(self.id, message, **kwargs):
91
- yield chunk
92
-
93
- def update(self, **kwargs) -> "Agent":
94
- """Update agent attributes."""
95
- if not self._client:
96
- raise RuntimeError(_AGENT_CLIENT_REQUIRED_MSG)
97
- updated_agent = self._client.update_agent(self.id, **kwargs)
98
- # Update current instance with new data
99
- for key, value in updated_agent.model_dump().items():
100
- if hasattr(self, key):
101
- setattr(self, key, value)
102
- return self
103
-
104
- def delete(self) -> None:
105
- """Delete the agent."""
106
- if not self._client:
107
- raise RuntimeError(_AGENT_CLIENT_REQUIRED_MSG)
108
- self._client.delete_agent(self.id)
109
-
110
-
111
- class Tool(BaseModel):
112
- """Tool model for API responses."""
113
-
114
- id: str
115
- name: str
116
- tool_type: str | None = None
117
- description: str | None = None
118
- framework: str | None = None
119
- version: str | None = None
120
- tool_script: str | None = None
121
- tool_file: str | None = None
122
- tags: str | list[str] | None = None
123
- _client: Any = None # Will hold client reference
124
-
125
- def _set_client(self, client: Any) -> "Tool":
126
- """Set the client reference for this resource."""
127
- self._client = client
128
- return self
129
-
130
- def get_script(self) -> str:
131
- """Get the tool script content."""
132
- if self.tool_script:
133
- return self.tool_script
134
- elif self.tool_file:
135
- return f"Script content from file: {self.tool_file}"
136
- else:
137
- return "No script content available"
138
-
139
- def update(self, **kwargs) -> "Tool":
140
- """Update tool attributes.
141
-
142
- Supports both metadata updates and file uploads.
143
- Pass 'file' parameter to update tool code via file upload.
144
- """
145
- if not self._client:
146
- raise RuntimeError("No client available. Use client.get_tool_by_id() to get a client-connected tool.")
147
-
148
- # Check if file upload is requested
149
- if "file" in kwargs:
150
- file_path = kwargs.pop("file") # Remove file from kwargs for metadata
151
- updated_tool = self._client.tools.update_tool_via_file(self.id, file_path, **kwargs)
152
- else:
153
- # Regular metadata update
154
- updated_tool = self._client.tools.update_tool(self.id, **kwargs)
155
-
156
- # Update current instance with new data
157
- for key, value in updated_tool.model_dump().items():
158
- if hasattr(self, key):
159
- setattr(self, key, value)
160
- return self
161
-
162
- def delete(self) -> None:
163
- """Delete the tool."""
164
- if not self._client:
165
- raise RuntimeError("No client available. Use client.get_tool_by_id() to get a client-connected tool.")
166
- self._client.delete_tool(self.id)
167
-
168
-
169
- class MCP(BaseModel):
170
- """MCP model for API responses."""
171
-
172
- id: str
173
- name: str
174
- description: str | None = None
175
- config: dict[str, Any] | None = None
176
- transport: str | None = None # "sse" or "http"
177
- authentication: dict[str, Any] | None = None
178
- metadata: dict[str, Any] | None = None
179
- _client: Any = None # Will hold client reference
180
-
181
- def _set_client(self, client: Any) -> "MCP":
182
- """Set the client reference for this resource."""
183
- self._client = client
184
- return self
185
-
186
- def get_tools(self) -> list[dict[str, Any]]:
187
- """Get tools available from this MCP."""
188
- if not self._client:
189
- raise RuntimeError(_MCP_CLIENT_REQUIRED_MSG)
190
- # This would delegate to the client's MCP tools endpoint
191
- # For now, return empty list as placeholder
192
- return []
193
-
194
- def update(self, **kwargs) -> "MCP":
195
- """Update MCP attributes."""
196
- if not self._client:
197
- raise RuntimeError(_MCP_CLIENT_REQUIRED_MSG)
198
- updated_mcp = self._client.update_mcp(self.id, **kwargs)
199
- # Update current instance with new data
200
- for key, value in updated_mcp.model_dump().items():
201
- if hasattr(self, key):
202
- setattr(self, key, value)
203
- return self
204
-
205
- def delete(self) -> None:
206
- """Delete the MCP."""
207
- if not self._client:
208
- raise RuntimeError("No client available. Use client.get_mcp_by_id() to get a client-connected MCP.")
209
- self._client.delete_mcp(self.id)
210
-
211
-
212
- class LanguageModelResponse(BaseModel):
213
- """Language model response model."""
214
-
215
- name: str
216
- provider: str
217
- description: str | None = None
218
- capabilities: list[str] | None = None
219
- max_tokens: int | None = None
220
- supports_streaming: bool = False
221
-
222
-
223
- class TTYRenderer:
224
- """Simple TTY renderer for non-Rich environments."""
225
-
226
- def __init__(self, use_color: bool = True):
227
- """Initialize the TTY renderer.
228
-
229
- Args:
230
- use_color: Whether to use color output
231
- """
232
- self.use_color = use_color
233
-
234
- def render_message(self, message: str, event_type: str = "message") -> None:
235
- """Render a message with optional color."""
236
- if event_type == "error":
237
- print(f"ERROR: {message}", flush=True)
238
- elif event_type == "done":
239
- print(f"\n✅ {message}", flush=True)
240
- else:
241
- print(message, flush=True)