pyagentkit 0.1.0__tar.gz → 0.1.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.
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/PKG-INFO +2 -2
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/README.md +1 -1
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/pyproject.toml +1 -1
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/src/pyagentkit/__init__.py +6 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/src/pyagentkit/agent.py +21 -27
- pyagentkit-0.1.4/src/pyagentkit/helpers.py +16 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/.github/workflows/publish.yml +0 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/.github/workflows/python-publish.yml +0 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/.gitignore +0 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/.python-version +0 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/LICENSE +0 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/USAGE.md +0 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/src/pyagentkit/definitions.py +0 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/src/pyagentkit/exceptions.py +0 -0
- {pyagentkit-0.1.0 → pyagentkit-0.1.4}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyagentkit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Agent toolkit for Ollama
|
|
5
5
|
Project-URL: Homepage, https://github.com/TarikEren/pyagentkit
|
|
6
6
|
Project-URL: Issues, https://github.com/TarikEren/pyagentkit/issues
|
|
@@ -35,7 +35,7 @@ Lightweight library for creating tool-enabled AI agents using Ollama. Including
|
|
|
35
35
|
- Schema validation for tool inputs
|
|
36
36
|
- Structured and validated agent responses
|
|
37
37
|
|
|
38
|
-
## Installation
|
|
38
|
+
## Installation
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
41
|
pip install pyagentkit
|
|
@@ -15,7 +15,7 @@ Lightweight library for creating tool-enabled AI agents using Ollama. Including
|
|
|
15
15
|
- Schema validation for tool inputs
|
|
16
16
|
- Structured and validated agent responses
|
|
17
17
|
|
|
18
|
-
## Installation
|
|
18
|
+
## Installation
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
pip install pyagentkit
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from .agent import Agent
|
|
2
3
|
from .definitions import (
|
|
3
4
|
ToolResult,
|
|
@@ -13,6 +14,10 @@ from .exceptions import (
|
|
|
13
14
|
ToolExceptionFatal,
|
|
14
15
|
)
|
|
15
16
|
|
|
17
|
+
from .helpers import configure_logging
|
|
18
|
+
|
|
19
|
+
logging.getLogger("pyagentkit").addHandler(logging.NullHandler())
|
|
20
|
+
|
|
16
21
|
__all__ = [
|
|
17
22
|
"Agent",
|
|
18
23
|
"ToolResult",
|
|
@@ -24,4 +29,5 @@ __all__ = [
|
|
|
24
29
|
"AgentExceptionFatal",
|
|
25
30
|
"ToolExceptionError",
|
|
26
31
|
"ToolExceptionFatal",
|
|
32
|
+
"configure_logging",
|
|
27
33
|
]
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import re
|
|
2
2
|
import json
|
|
3
|
+
import logging
|
|
3
4
|
import inspect
|
|
4
5
|
from typing import (
|
|
5
6
|
ClassVar,
|
|
@@ -32,6 +33,8 @@ from .exceptions import (
|
|
|
32
33
|
|
|
33
34
|
T = TypeVar("T", bound=AgentResponse)
|
|
34
35
|
|
|
36
|
+
logger = logging.getLogger("pyagentkit")
|
|
37
|
+
|
|
35
38
|
|
|
36
39
|
class Agent(Generic[T]):
|
|
37
40
|
"""Allows easier agent creation"""
|
|
@@ -298,18 +301,19 @@ class Agent(Generic[T]):
|
|
|
298
301
|
raise ToolExceptionError(
|
|
299
302
|
f"Tool `{tool_call.name}` not found, check the tool name and respond with a valid tool name",
|
|
300
303
|
)
|
|
301
|
-
|
|
302
|
-
|
|
304
|
+
choice = (
|
|
305
|
+
input(
|
|
306
|
+
f"[Info] Agent {self.agent_name} wants to call tool {tool_name} with params:\n{'.'.join(param for param in tool_params)}\nAllow tool call? (Y/n): "
|
|
307
|
+
)
|
|
308
|
+
.lower()
|
|
309
|
+
.strip()
|
|
303
310
|
)
|
|
304
|
-
for param in tool_params:
|
|
305
|
-
print("-", param)
|
|
306
|
-
choice = input("Allow tool call? (Y/n): ").lower().strip()
|
|
307
311
|
if choice not in ["y", ""]:
|
|
308
|
-
|
|
312
|
+
logger.info("Cancelled tool call")
|
|
309
313
|
self.message_history.append(
|
|
310
314
|
{
|
|
311
315
|
"role": "user",
|
|
312
|
-
"content": f"Tool `{tool_name}` with params `{tool_params}` has been rejected by the user. Generate final response
|
|
316
|
+
"content": f"Tool `{tool_name}` with params `{tool_params}` has been rejected by the user. Generate final response telling what the user should do in order to finish the task",
|
|
313
317
|
}
|
|
314
318
|
)
|
|
315
319
|
self.tool_try += 1
|
|
@@ -345,11 +349,11 @@ class Agent(Generic[T]):
|
|
|
345
349
|
parts = []
|
|
346
350
|
if unknown:
|
|
347
351
|
unknown_message = f"Unknown parameters {sorted(unknown)}"
|
|
348
|
-
|
|
352
|
+
logger.warning("%s", unknown_message)
|
|
349
353
|
parts.append(unknown_message)
|
|
350
354
|
if missing:
|
|
351
355
|
missing_message = f"Missing required parameters: {sorted(missing)}"
|
|
352
|
-
|
|
356
|
+
logger.warning("%s", missing_message)
|
|
353
357
|
parts.append(missing_message)
|
|
354
358
|
valid_list = [
|
|
355
359
|
f"{name}: {inspect.formatannotation(p.annotation) if p.annotation is not inspect.Parameter.empty else 'any'}"
|
|
@@ -362,8 +366,10 @@ class Agent(Generic[T]):
|
|
|
362
366
|
try:
|
|
363
367
|
tool_return = accepted_tool.function(**kwargs)
|
|
364
368
|
except TypeError as exc:
|
|
365
|
-
|
|
366
|
-
|
|
369
|
+
logger.warning(
|
|
370
|
+
"Called tool `%s` with invalid arguments `%s`",
|
|
371
|
+
tool_name,
|
|
372
|
+
kwargs,
|
|
367
373
|
)
|
|
368
374
|
raise ToolExceptionError(
|
|
369
375
|
f"Tool `{tool_name}` call failed with invalid arguments: {exc}. "
|
|
@@ -399,8 +405,6 @@ If task is done, generate `final` response and stop.""",
|
|
|
399
405
|
|
|
400
406
|
def handle_response(self, prompt: str, deps: AgentDependencies | None = None) -> T:
|
|
401
407
|
response_try = 0
|
|
402
|
-
# Send prompt to agent
|
|
403
|
-
# print(f"[DEBUG]: System prompt: {self.message_history[0]}")
|
|
404
408
|
compiled_system_prompt = f"""{self.base_system_prompt}
|
|
405
409
|
|
|
406
410
|
{self._build_schema_prompt()}
|
|
@@ -426,8 +430,7 @@ If task is done, generate `final` response and stop.""",
|
|
|
426
430
|
{"role": "user", "content": prompt},
|
|
427
431
|
)
|
|
428
432
|
while response_try < self.response_retries:
|
|
429
|
-
|
|
430
|
-
# print(f"[DEBUG]: Response Try: {response_try}, Tool Try: {self.tool_try}")
|
|
433
|
+
logger.debug("Response try: %s", response_try)
|
|
431
434
|
try:
|
|
432
435
|
response = self.ollama_client.chat(
|
|
433
436
|
model=self.llm_name,
|
|
@@ -435,25 +438,19 @@ If task is done, generate `final` response and stop.""",
|
|
|
435
438
|
options={"num_ctx": self.num_ctx},
|
|
436
439
|
)
|
|
437
440
|
content = response.message.content
|
|
438
|
-
print(f"[DEBUG] Content:\n{content}")
|
|
439
441
|
if content is None:
|
|
440
442
|
raise RuntimeError(
|
|
441
443
|
f"Failed to get response from agent {self.agent_name}"
|
|
442
444
|
)
|
|
445
|
+
logger.debug("Content from agent %s:\n%s", self.agent_name, content)
|
|
443
446
|
|
|
444
447
|
# Append the assistant message because it doesn't know that it
|
|
445
448
|
# actually did anything
|
|
446
449
|
self.message_history.append({"role": "assistant", "content": content})
|
|
447
450
|
|
|
448
|
-
# Get rid of markdown fences because some models are stupid
|
|
449
|
-
# stripped = self._strip_markdown_formatting(message=content)
|
|
450
|
-
# print(f"[DEBUG] Stripped: {stripped}")
|
|
451
|
-
# validated = self.response_model.model_validate_json(stripped)
|
|
452
|
-
|
|
453
451
|
validated = self.response_model.model_validate_json(content)
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
print(f"[{self.agent_name}]: {validated.message}")
|
|
452
|
+
|
|
453
|
+
logger.info("[%s]: %s", self.agent_name, validated.message)
|
|
457
454
|
self._validate_agent_logic(response=validated)
|
|
458
455
|
if validated.response.type == "final":
|
|
459
456
|
return validated
|
|
@@ -465,9 +462,6 @@ If task is done, generate `final` response and stop.""",
|
|
|
465
462
|
self._handle_tool_call(tool_call=tool_call)
|
|
466
463
|
|
|
467
464
|
except ValidationError as exc:
|
|
468
|
-
print(
|
|
469
|
-
f"[DEBUG] Validation error string: {self._print_validation_errors(exc.errors())}"
|
|
470
|
-
)
|
|
471
465
|
self.message_history.append(
|
|
472
466
|
{
|
|
473
467
|
"role": "user",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def configure_logging(level: int = logging.INFO) -> None:
|
|
5
|
+
"""
|
|
6
|
+
Enables pyagentkit log output.
|
|
7
|
+
Call this at the start of your script to see agent messages.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
level: Logging level (default: logging.INFO)
|
|
11
|
+
"""
|
|
12
|
+
logger = logging.getLogger("pyagentkit")
|
|
13
|
+
handler = logging.StreamHandler()
|
|
14
|
+
handler.setFormatter(logging.Formatter("%(message)s"))
|
|
15
|
+
logger.addHandler(handler)
|
|
16
|
+
logger.setLevel(level)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|