acontext 0.0.17__py3-none-any.whl → 0.1.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.
@@ -12,8 +12,6 @@ from ..types.skill import (
12
12
  GetSkillFileResp,
13
13
  ListSkillsOutput,
14
14
  Skill,
15
- SkillCatalogItem,
16
- _ListSkillsResponse,
17
15
  )
18
16
  from ..uploads import FileUpload, normalize_file_upload
19
17
 
@@ -84,31 +82,19 @@ class AsyncSkillsAPI:
84
82
  data = await self._requester.request(
85
83
  "GET", "/agent_skills", params=params or None
86
84
  )
87
- api_response = _ListSkillsResponse.model_validate(data)
88
-
89
- # Convert to catalog format (name and description only)
90
- return ListSkillsOutput(
91
- items=[
92
- SkillCatalogItem(name=skill.name, description=skill.description)
93
- for skill in api_response.items
94
- ],
95
- next_cursor=api_response.next_cursor,
96
- has_more=api_response.has_more,
97
- )
85
+ # Pydantic ignores extra fields, so ListSkillsOutput directly extracts name/description
86
+ return ListSkillsOutput.model_validate(data)
98
87
 
99
- async def get_by_name(self, name: str) -> Skill:
100
- """Get a skill by its name.
88
+ async def get(self, skill_id: str) -> Skill:
89
+ """Get a skill by its ID.
101
90
 
102
91
  Args:
103
- name: The name of the skill (unique within project).
92
+ skill_id: The UUID of the skill.
104
93
 
105
94
  Returns:
106
- Skill containing the skill information.
95
+ Skill containing the full skill information including file_index.
107
96
  """
108
- params = {"name": name}
109
- data = await self._requester.request(
110
- "GET", "/agent_skills/by_name", params=params
111
- )
97
+ data = await self._requester.request("GET", f"/agent_skills/{skill_id}")
112
98
  return Skill.model_validate(data)
113
99
 
114
100
  async def delete(self, skill_id: str) -> None:
@@ -119,32 +105,31 @@ class AsyncSkillsAPI:
119
105
  """
120
106
  await self._requester.request("DELETE", f"/agent_skills/{skill_id}")
121
107
 
122
- async def get_file_by_name(
108
+ async def get_file(
123
109
  self,
124
110
  *,
125
- skill_name: str,
111
+ skill_id: str,
126
112
  file_path: str,
127
113
  expire: int | None = None,
128
114
  ) -> GetSkillFileResp:
129
- """Get a file from a skill by name.
115
+ """Get a file from a skill by skill ID.
130
116
 
131
117
  The backend automatically returns content for parseable text files, or a presigned URL
132
118
  for non-parseable files (binary, images, etc.).
133
119
 
134
120
  Args:
135
- skill_name: The name of the skill.
121
+ skill_id: The UUID of the skill.
136
122
  file_path: Relative path to the file within the skill (e.g., 'scripts/extract_text.json').
137
123
  expire: URL expiration time in seconds. Defaults to 900 (15 minutes).
138
124
 
139
125
  Returns:
140
126
  GetSkillFileResp containing the file path, MIME type, and either content or URL.
141
127
  """
142
- endpoint = f"/agent_skills/by_name/{skill_name}/file"
128
+ endpoint = f"/agent_skills/{skill_id}/file"
143
129
 
144
- params = {"file_path": file_path}
130
+ params: dict[str, Any] = {"file_path": file_path}
145
131
  if expire is not None:
146
132
  params["expire"] = expire
147
133
 
148
134
  data = await self._requester.request("GET", endpoint, params=params)
149
135
  return GetSkillFileResp.model_validate(data)
150
-
@@ -12,8 +12,6 @@ from ..types.skill import (
12
12
  GetSkillFileResp,
13
13
  ListSkillsOutput,
14
14
  Skill,
15
- SkillCatalogItem,
16
- _ListSkillsResponse,
17
15
  )
18
16
  from ..uploads import FileUpload, normalize_file_upload
19
17
 
@@ -25,9 +23,11 @@ class SkillsAPI:
25
23
  def create(
26
24
  self,
27
25
  *,
28
- file: FileUpload
29
- | tuple[str, BinaryIO | bytes]
30
- | tuple[str, BinaryIO | bytes, str],
26
+ file: (
27
+ FileUpload
28
+ | tuple[str, BinaryIO | bytes]
29
+ | tuple[str, BinaryIO | bytes, str]
30
+ ),
31
31
  user: str | None = None,
32
32
  meta: Mapping[str, Any] | None = None,
33
33
  ) -> Skill:
@@ -80,31 +80,23 @@ class SkillsAPI:
80
80
  along with pagination information (next_cursor and has_more).
81
81
  """
82
82
  effective_limit = limit if limit is not None else 100
83
- params = build_params(user=user, limit=effective_limit, cursor=cursor, time_desc=time_desc)
84
- data = self._requester.request("GET", "/agent_skills", params=params or None)
85
- api_response = _ListSkillsResponse.model_validate(data)
86
-
87
- # Convert to catalog format (name and description only)
88
- return ListSkillsOutput(
89
- items=[
90
- SkillCatalogItem(name=skill.name, description=skill.description)
91
- for skill in api_response.items
92
- ],
93
- next_cursor=api_response.next_cursor,
94
- has_more=api_response.has_more,
83
+ params = build_params(
84
+ user=user, limit=effective_limit, cursor=cursor, time_desc=time_desc
95
85
  )
86
+ data = self._requester.request("GET", "/agent_skills", params=params or None)
87
+ # Pydantic ignores extra fields, so ListSkillsOutput directly extracts name/description
88
+ return ListSkillsOutput.model_validate(data)
96
89
 
97
- def get_by_name(self, name: str) -> Skill:
98
- """Get a skill by its name.
90
+ def get(self, skill_id: str) -> Skill:
91
+ """Get a skill by its ID.
99
92
 
100
93
  Args:
101
- name: The name of the skill (unique within project).
94
+ skill_id: The UUID of the skill.
102
95
 
103
96
  Returns:
104
- Skill containing the skill information.
97
+ Skill containing the full skill information including file_index.
105
98
  """
106
- params = {"name": name}
107
- data = self._requester.request("GET", "/agent_skills/by_name", params=params)
99
+ data = self._requester.request("GET", f"/agent_skills/{skill_id}")
108
100
  return Skill.model_validate(data)
109
101
 
110
102
  def delete(self, skill_id: str) -> None:
@@ -115,32 +107,31 @@ class SkillsAPI:
115
107
  """
116
108
  self._requester.request("DELETE", f"/agent_skills/{skill_id}")
117
109
 
118
- def get_file_by_name(
110
+ def get_file(
119
111
  self,
120
112
  *,
121
- skill_name: str,
113
+ skill_id: str,
122
114
  file_path: str,
123
115
  expire: int | None = None,
124
116
  ) -> GetSkillFileResp:
125
- """Get a file from a skill by name.
117
+ """Get a file from a skill by skill ID.
126
118
 
127
119
  The backend automatically returns content for parseable text files, or a presigned URL
128
120
  for non-parseable files (binary, images, etc.).
129
121
 
130
122
  Args:
131
- skill_name: The name of the skill.
123
+ skill_id: The UUID of the skill.
132
124
  file_path: Relative path to the file within the skill (e.g., 'scripts/extract_text.json').
133
125
  expire: URL expiration time in seconds. Defaults to 900 (15 minutes).
134
126
 
135
127
  Returns:
136
128
  GetSkillFileResp containing the file path, MIME type, and either content or URL.
137
129
  """
138
- endpoint = f"/agent_skills/by_name/{skill_name}/file"
130
+ endpoint = f"/agent_skills/{skill_id}/file"
139
131
 
140
- params = {"file_path": file_path}
132
+ params: dict[str, Any] = {"file_path": file_path}
141
133
  if expire is not None:
142
134
  params["expire"] = expire
143
135
 
144
136
  data = self._requester.request("GET", endpoint, params=params)
145
137
  return GetSkillFileResp.model_validate(data)
146
-
acontext/types/skill.py CHANGED
@@ -24,9 +24,7 @@ class Skill(BaseModel):
24
24
  file_index: list[FileInfo] = Field(
25
25
  ..., description="List of file information (path and MIME type) in the skill"
26
26
  )
27
- meta: dict[str, Any] | None = Field(
28
- None, description="Custom metadata dictionary"
29
- )
27
+ meta: dict[str, Any] | None = Field(None, description="Custom metadata dictionary")
30
28
  created_at: str = Field(..., description="ISO 8601 formatted creation timestamp")
31
29
  updated_at: str = Field(..., description="ISO 8601 formatted update timestamp")
32
30
 
@@ -39,7 +37,11 @@ class SkillCatalogItem(BaseModel):
39
37
 
40
38
 
41
39
  class ListSkillsOutput(BaseModel):
42
- """Response model for listing skills (catalog format with name and description only)."""
40
+ """Response model for listing skills (catalog format with name and description only).
41
+
42
+ Pydantic ignores extra fields, so this directly parses API responses
43
+ and extracts only name/description from each item.
44
+ """
43
45
 
44
46
  items: list[SkillCatalogItem] = Field(
45
47
  ..., description="List of skills with name and description"
@@ -48,22 +50,16 @@ class ListSkillsOutput(BaseModel):
48
50
  has_more: bool = Field(..., description="Whether there are more items")
49
51
 
50
52
 
51
- class _ListSkillsResponse(BaseModel):
52
- """Internal response model for API pagination (full Skill objects).
53
-
54
- This is used internally to parse the raw API response before converting
55
- to the catalog format (ListSkillsOutput).
56
- """
57
- items: list[Skill]
58
- next_cursor: str | None = None
59
- has_more: bool = False
60
-
61
-
62
53
  class GetSkillFileResp(BaseModel):
63
54
  """Response model for getting a skill file."""
64
55
 
65
56
  path: str = Field(..., description="File path")
66
57
  mime: str = Field(..., description="MIME type of the file")
67
- url: str | None = Field(None, description="Presigned URL for downloading the file (present if file is not parseable)")
68
- content: FileContent | None = Field(None, description="Parsed file content if available (present if file is parseable)")
69
-
58
+ url: str | None = Field(
59
+ None,
60
+ description="Presigned URL for downloading the file (present if file is not parseable)",
61
+ )
62
+ content: FileContent | None = Field(
63
+ None,
64
+ description="Parsed file content if available (present if file is parseable)",
65
+ )
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: acontext
3
- Version: 0.0.17
3
+ Version: 0.1.0
4
4
  Summary: Python SDK for the Acontext API
5
5
  Keywords: acontext,sdk,client,api
6
6
  Requires-Dist: httpx>=0.28.1
7
7
  Requires-Dist: openai>=2.6.1
8
8
  Requires-Dist: anthropic>=0.72.0
9
9
  Requires-Dist: pydantic>=2.12.3
10
+ Requires-Dist: urllib3>=2.6.3
10
11
  Requires-Python: >=3.10
11
12
  Project-URL: Homepage, https://github.com/memodb-io/Acontext
12
13
  Project-URL: Issues, https://github.com/memodb-io/Acontext/issues
@@ -1,10 +1,10 @@
1
1
  acontext/__init__.py,sha256=jAgRawWIjyMd6g3gq7Xm_3vNB31cPj8rMFPO4LGQKdM,1027
2
2
  acontext/_constants.py,sha256=Ikuy_Wz3CPmXjKPLXb4Y580-fe54o1hZ2ZB1Bpw3sFE,363
3
3
  acontext/_utils.py,sha256=GKQH45arKh0sDu64u-5jwrII_ctnU_oChYlgR5lRkfE,1250
4
- acontext/agent/__init__.py,sha256=PAUhm1rBYOdKw3lCD-H9d72emkGL4KoxEvVq4GeS9ig,158
5
- acontext/agent/base.py,sha256=kN2KzV6fOlvmMSi_0yu2QqwVLtHh09TznAy_SDtC8iM,2998
6
- acontext/agent/disk.py,sha256=dSDjCejP0o4Z4nHJgfKfIXLFZaCA9AFV852Yo9E9GHk,16131
7
- acontext/agent/skill.py,sha256=opsOTQyuedqQMlwDXWMVwCwg0u9cyehfyELDEbat3bE,4451
4
+ acontext/agent/__init__.py,sha256=0lIRRDk-sCtLelpNiWYIEKzKC5a8bWJge2vp9Wqnibk,157
5
+ acontext/agent/base.py,sha256=RcHiWVDJwfkPl_3ycEqFxW3S4pXGTwXo3bV6qzXTkBw,3459
6
+ acontext/agent/disk.py,sha256=pIz9xFULG3k0KKSvilz6jZskIvp3mGHhkOxQIUQTNZs,22367
7
+ acontext/agent/skill.py,sha256=sPKhnTobE9NG88-OeZFyZLT4jahjTXZsuSy2vD4_NlA,13017
8
8
  acontext/async_client.py,sha256=sqdSNjl3tx8ijoRNYoEwh1Lxdlhfk0zyd-h-xffIJJE,8372
9
9
  acontext/client.py,sha256=3xha-zbHYLwI1njlhmoB_BYK5JIJoXFyrCpvIi63b9o,8097
10
10
  acontext/client_types.py,sha256=uVBWzLbZyXrqkljG49ojdQL_xX6N3n_HGt4Bs_TEE48,987
@@ -13,16 +13,16 @@ acontext/messages.py,sha256=oNRZStfhcPFt6DPOfs_-Q7R1Xui6dOMr3wmpmC8pzvE,2310
13
13
  acontext/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  acontext/resources/__init__.py,sha256=Oww11t9hmwdNFK2nC8YW9mf4BBSz5YLPAXAWLlZuNTs,935
15
15
  acontext/resources/async_blocks.py,sha256=e_iJpgcAdwS2tXQ16MMCnySlddp5JV3BadN_EyqZSF4,5555
16
- acontext/resources/async_disks.py,sha256=rwcRwQ79ZYbMMWAj5YDDpKQmfAIOl9M3CTYxOZTy_UU,6830
17
- acontext/resources/async_sessions.py,sha256=Ld9T8l884r3UuUprRz7MwafSI8BaPfLA0pg0dPfNM1A,14363
18
- acontext/resources/async_skills.py,sha256=mbEzyUH7S2_jkZ5tfl0FzpHJ7Io3x_biw5FirhokzAQ,5062
16
+ acontext/resources/async_disks.py,sha256=1kq9DpU7gXEhYkKGUlMyVyi8GPVSwYHjD_iEBv1UocQ,9024
17
+ acontext/resources/async_sessions.py,sha256=DCGVohFrYpJZzERVzUlLr2xBxf_bzIUKD3EFhJ26S0I,14726
18
+ acontext/resources/async_skills.py,sha256=VoeqO9Z6E7qPCE2tMJaO7coONaCKCoLJRANQ5yWVbiE,4666
19
19
  acontext/resources/async_spaces.py,sha256=b8DNG2L43B6iSgfmH8M-0cxAp681IjSCjw-4alfjV2A,6712
20
20
  acontext/resources/async_tools.py,sha256=RbGaF2kX65Mun-q-Fp5H1J8waWTLIdCOfbdY19jpn1o,1091
21
21
  acontext/resources/async_users.py,sha256=m0nK_Luo6Uuvw2azGx8Wg2cXnipnTnyheolr79fX16Y,2020
22
22
  acontext/resources/blocks.py,sha256=HJdAy5HdyTcHCYCPmqNdvApYKZ6aWs-ORIi_wQt3TUM,5447
23
23
  acontext/resources/disks.py,sha256=pvxs9gdVBothuy0LSkPmuS061nNOgJX3iffypqLHW1Y,9032
24
24
  acontext/resources/sessions.py,sha256=qUoLs01tzmYChHy3kozzGQ3ZeAz_JyWGtCIsVL20BO4,14491
25
- acontext/resources/skills.py,sha256=FPp1YWhH85I9BU0fJJC9FbePIbFhyX6j2FYxjPuBEAc,4935
25
+ acontext/resources/skills.py,sha256=ZECLUfy4QWHnzk9nnq1VvEeFTx-u7NvEhECfbq5Reiw,4615
26
26
  acontext/resources/spaces.py,sha256=Ktvkkn3Jj7CZoKMbn6fYuo0zqImoCWj2EnMsnL2q-0A,6571
27
27
  acontext/resources/tools.py,sha256=II_185B0HYKSP43hizE6C1zs7kjkkPLKihuEG8s-DRY,1046
28
28
  acontext/resources/users.py,sha256=6xwU7UeMWRIGn6n7LKgsptV9pzYFNWCbJftieptVg6k,1961
@@ -31,11 +31,11 @@ acontext/types/block.py,sha256=CzKByunk642rWXNNnh8cx67UzKLKDAxODmC_whwjP90,1078
31
31
  acontext/types/common.py,sha256=5kLwzszlIofz8qZ9-Wj_zcBBiF22mAWgH9uWPkcgWCE,327
32
32
  acontext/types/disk.py,sha256=nMjyXLUre4Xuu_YfBbzzdRQDRxB8qX1Zx9LsNqGCi9E,2223
33
33
  acontext/types/session.py,sha256=WIaTiiAw8OujeSnk18Vy_Fn_AffW60pfs-unlPXYuT8,11076
34
- acontext/types/skill.py,sha256=qBDNysW9ptKX6RcMiZd4PfwWwvcYCzj_dC-6RbXqyx4,2531
34
+ acontext/types/skill.py,sha256=VlLp5NpsJSpyoQTlTuV6jJ4G6ArHr1SDpcqEmFkHyeY,2364
35
35
  acontext/types/space.py,sha256=9BkGBYGeQDVwYTmPLoIjMY-IUdQzjrt8I7CXca2_5Vc,2600
36
36
  acontext/types/tool.py,sha256=-mVn-vgk2SENK0Ubt-ZgWFZxKa-ddABqcAgXQ69YY-E,805
37
37
  acontext/types/user.py,sha256=JjE0xZDwUAs2BL741U7NINyyPAso64A1YmgMBPqSuvo,1331
38
38
  acontext/uploads.py,sha256=6twnqQOY_eerNuEjeSKsE_3S0IfJUiczXtAy4aXqDl8,1379
39
- acontext-0.0.17.dist-info/WHEEL,sha256=eycQt0QpYmJMLKpE3X9iDk8R04v2ZF0x82ogq-zP6bQ,79
40
- acontext-0.0.17.dist-info/METADATA,sha256=Z6rVfzFv3K3o_hSyymhrvdQU2ZGZ20GEwQPjPkNR7Rw,859
41
- acontext-0.0.17.dist-info/RECORD,,
39
+ acontext-0.1.0.dist-info/WHEEL,sha256=XjEbIc5-wIORjWaafhI6vBtlxDBp7S9KiujWF1EM7Ak,79
40
+ acontext-0.1.0.dist-info/METADATA,sha256=KXOlyw54Vjq-wPK8zVSt77DG8eJPm7nstGsnm8C7vZc,888
41
+ acontext-0.1.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.24
2
+ Generator: uv 0.9.25
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any