agentseek 0.0.1__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.
- agentseek/__init__.py +3 -0
- agentseek/__main__.py +75 -0
- agentseek/cli.py +163 -0
- agentseek/env.py +114 -0
- agentseek-0.0.1.dist-info/METADATA +140 -0
- agentseek-0.0.1.dist-info/RECORD +36 -0
- agentseek-0.0.1.dist-info/WHEEL +4 -0
- agentseek-0.0.1.dist-info/entry_points.txt +5 -0
- agentseek-0.0.1.dist-info/licenses/LICENSE +202 -0
- skills/README.md +5 -0
- skills/friendly-python/SKILL.md +47 -0
- skills/friendly-python/agents/openai.yaml +4 -0
- skills/friendly-python/references/api-design.md +56 -0
- skills/friendly-python/references/cli-argparse.md +44 -0
- skills/friendly-python/references/error-handling.md +59 -0
- skills/friendly-python/references/extension-architecture.md +63 -0
- skills/friendly-python/references/oop-design.md +67 -0
- skills/friendly-python/references/portability-pythonic.md +75 -0
- skills/friendly-python/references/principles.md +54 -0
- skills/friendly-python/references/reuse-composition.md +46 -0
- skills/friendly-python/references/review-checklist.md +45 -0
- skills/piglet/SKILL.md +45 -0
- skills/piglet/agents/openai.yaml +4 -0
- skills/piglet/references/decorators.md +52 -0
- skills/piglet/references/edge-cases.md +36 -0
- skills/piglet/references/exceptions-handling.md +60 -0
- skills/piglet/references/functions-and-returns.md +57 -0
- skills/piglet/references/if-else-and-branches.md +47 -0
- skills/piglet/references/imports-and-structure.md +42 -0
- skills/piglet/references/loops-and-iteration.md +34 -0
- skills/piglet/references/rules-and-file-io.md +72 -0
- skills/piglet/references/solid-python.md +62 -0
- skills/piglet/references/values-and-containers.md +62 -0
- skills/piglet/references/variables-and-naming.md +42 -0
- skills/piglet/references/walrus-operator.md +46 -0
- skills/plugin-creator/SKILL.md +368 -0
agentseek/__init__.py
ADDED
agentseek/__main__.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
4
|
+
import sys
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
import logfire
|
|
8
|
+
import logfire.integrations.loguru as logfire_loguru
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from agentseek.cli import apply_agentseek_cli_overrides
|
|
12
|
+
from agentseek.env import (
|
|
13
|
+
agentseek_config_file,
|
|
14
|
+
apply_agentseek_env_aliases,
|
|
15
|
+
get_agentseek_settings,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
apply_agentseek_env_aliases()
|
|
19
|
+
apply_agentseek_cli_overrides()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _maybe_enable_observability() -> None:
|
|
23
|
+
try:
|
|
24
|
+
observability = importlib.import_module("agentseek_observability.plugin")
|
|
25
|
+
except ModuleNotFoundError:
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
instrument = getattr(observability, "instrument_agentseek_observability", None)
|
|
29
|
+
if callable(instrument):
|
|
30
|
+
instrument()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _logfire_console_config(enabled: bool) -> logfire.ConsoleOptions | Literal[False]:
|
|
34
|
+
if not enabled:
|
|
35
|
+
return False
|
|
36
|
+
|
|
37
|
+
return logfire.ConsoleOptions()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _instrument_agentseek() -> None:
|
|
41
|
+
from loguru import logger
|
|
42
|
+
|
|
43
|
+
logger.remove()
|
|
44
|
+
logger.add(sys.stderr, colorize=True)
|
|
45
|
+
|
|
46
|
+
settings = get_agentseek_settings()
|
|
47
|
+
logfire.configure(send_to_logfire=False, console=_logfire_console_config(settings.console))
|
|
48
|
+
logger.add(logfire_loguru.LogfireHandler(), format="{message}")
|
|
49
|
+
_maybe_enable_observability()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def create_cli_app() -> typer.Typer:
|
|
53
|
+
from bub.framework import BubFramework
|
|
54
|
+
|
|
55
|
+
_instrument_agentseek()
|
|
56
|
+
framework = BubFramework(config_file=agentseek_config_file())
|
|
57
|
+
framework.load_hooks()
|
|
58
|
+
app = framework.create_cli_app()
|
|
59
|
+
|
|
60
|
+
if not app.registered_commands:
|
|
61
|
+
|
|
62
|
+
@app.command("help")
|
|
63
|
+
def _help() -> None:
|
|
64
|
+
typer.echo("No CLI command loaded.")
|
|
65
|
+
|
|
66
|
+
return app
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
app = create_cli_app()
|
|
70
|
+
|
|
71
|
+
__all__ = ["app", "create_cli_app"]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if __name__ == "__main__":
|
|
75
|
+
app()
|
agentseek/cli.py
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"""agentseek overrides for Bub's builtin CLI (onboard branding, install sandbox, …)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import contextlib
|
|
7
|
+
from collections.abc import Iterable
|
|
8
|
+
from importlib.metadata import PackageNotFoundError
|
|
9
|
+
from importlib.metadata import version as package_version
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
import typer
|
|
14
|
+
|
|
15
|
+
from agentseek.env import DEFAULT_PLUGIN_SANDBOX
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from bub.channels.cli import CliChannel
|
|
19
|
+
from bub.channels.cli.renderer import CliRenderer
|
|
20
|
+
from bub.channels.message import MessageKind
|
|
21
|
+
from rich.live import Live
|
|
22
|
+
|
|
23
|
+
AGENTSEEK_ONBOARD_BANNER = r"""
|
|
24
|
+
_ _ _
|
|
25
|
+
/ \ __ _ ___ _ __ | |_ ___ ___ ___| | __
|
|
26
|
+
/ _ \ / _` |/ _ \ '_ \| __/ __|/ _ \/ _ \ |/ /
|
|
27
|
+
/ ___ \ (_| | __/ | | | |_\__ \ __/ __/ <
|
|
28
|
+
/_/ \_\__, |\___|_| |_|\__|___/\___|\___|_|\_\
|
|
29
|
+
|___/
|
|
30
|
+
AGENTSEEK v{version}
|
|
31
|
+
""".strip("\n")
|
|
32
|
+
AGENTSEEK_ONBOARD_WELCOME = "\nWelcome to agentseek! Let's get you set up.\n"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def agentseek_version() -> str:
|
|
36
|
+
try:
|
|
37
|
+
return package_version("agentseek")
|
|
38
|
+
except PackageNotFoundError:
|
|
39
|
+
return "0.0.0"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _brand_onboard_echo(original_echo):
|
|
43
|
+
def echo(message=None, *args, **kwargs):
|
|
44
|
+
if message == "\nWelcome to Bub! Let's get you set up.\n":
|
|
45
|
+
message = AGENTSEEK_ONBOARD_WELCOME
|
|
46
|
+
return original_echo(message, *args, **kwargs)
|
|
47
|
+
|
|
48
|
+
return echo
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def resolve_enabled_channels(framework, primary_channels: Iterable[str]) -> list[str]:
|
|
52
|
+
"""Enable requested channels plus all lifecycle channels exposed by the framework."""
|
|
53
|
+
enabled = list(dict.fromkeys(primary_channels))
|
|
54
|
+
for channel_name in framework.get_channels(lambda _message: None):
|
|
55
|
+
if channel_name.endswith(".lifecycle") and channel_name not in enabled:
|
|
56
|
+
enabled.append(channel_name)
|
|
57
|
+
return enabled
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _install_single_cli_log_sink(self: CliChannel) -> int:
|
|
61
|
+
from loguru import logger
|
|
62
|
+
|
|
63
|
+
with contextlib.suppress(ValueError):
|
|
64
|
+
logger.remove()
|
|
65
|
+
return logger.add(self._renderer.log, colorize=False, format="{level:<8} | {message}")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _finish_cli_stream_once(self: CliRenderer, live: Live, *, kind: MessageKind, text: str) -> None:
|
|
69
|
+
del self
|
|
70
|
+
del kind, text
|
|
71
|
+
live.stop()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def apply_agentseek_onboard_branding() -> None:
|
|
75
|
+
"""Replace Bub's onboard banner and copy without changing the onboard workflow."""
|
|
76
|
+
from bub.builtin import cli
|
|
77
|
+
|
|
78
|
+
cli.ONBOARD_BANNER = AGENTSEEK_ONBOARD_BANNER
|
|
79
|
+
cli.typer.echo = _brand_onboard_echo(cli.typer.echo)
|
|
80
|
+
cli.__version__ = agentseek_version()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def apply_agentseek_chat_channel_defaults() -> None:
|
|
84
|
+
"""Include lifecycle channels in chat mode so MCP and similar helpers can boot."""
|
|
85
|
+
import bub.builtin.cli as bub_cli
|
|
86
|
+
from bub.channels.cli import CliChannel
|
|
87
|
+
from bub.channels.cli.renderer import CliRenderer
|
|
88
|
+
from bub.channels.manager import ChannelManager
|
|
89
|
+
from bub.framework import BubFramework
|
|
90
|
+
|
|
91
|
+
type.__setattr__(CliChannel, "_install_log_sink", _install_single_cli_log_sink)
|
|
92
|
+
type.__setattr__(CliRenderer, "finish_stream", _finish_cli_stream_once)
|
|
93
|
+
|
|
94
|
+
def chat(
|
|
95
|
+
ctx: typer.Context,
|
|
96
|
+
chat_id: str = bub_cli.typer.Option("local", "--chat-id", help="Chat id"),
|
|
97
|
+
session_id: str | None = bub_cli.typer.Option(None, "--session-id", help="Optional session id"),
|
|
98
|
+
) -> None:
|
|
99
|
+
framework = ctx.ensure_object(BubFramework)
|
|
100
|
+
manager = ChannelManager(
|
|
101
|
+
framework,
|
|
102
|
+
enabled_channels=resolve_enabled_channels(framework, ["cli"]),
|
|
103
|
+
stream_output=True,
|
|
104
|
+
)
|
|
105
|
+
channel = manager.get_channel("cli")
|
|
106
|
+
if not isinstance(channel, CliChannel):
|
|
107
|
+
bub_cli.typer.echo("CLI channel not found. Please check your hook implementations.")
|
|
108
|
+
raise bub_cli.typer.Exit(1)
|
|
109
|
+
channel.set_metadata(chat_id=chat_id, session_id=session_id)
|
|
110
|
+
asyncio.run(manager.listen_and_run())
|
|
111
|
+
|
|
112
|
+
object.__setattr__(bub_cli, "chat", chat)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def apply_agentseek_install_project_defaults() -> None:
|
|
116
|
+
"""Use :data:`~agentseek.env.DEFAULT_PLUGIN_SANDBOX` for Bub's plugin-install sandbox.
|
|
117
|
+
|
|
118
|
+
Bub defaults to ``uv init --name bub-project``. agentseek aligns ``uv init --name`` with the
|
|
119
|
+
default ``BUB_PROJECT`` path from :func:`~agentseek.env.apply_agentseek_env_aliases`.
|
|
120
|
+
"""
|
|
121
|
+
import bub.builtin.cli as bub_cli
|
|
122
|
+
|
|
123
|
+
def _ensure_plugin_sandbox(project: Path) -> None:
|
|
124
|
+
# Bub's own ``_default_project`` factory mkdir's the sandbox before
|
|
125
|
+
# returning the path. When ``BUB_PROJECT`` is supplied through the
|
|
126
|
+
# environment (which is what ``apply_agentseek_env_aliases`` does for
|
|
127
|
+
# ``.agentseek/agentseek-project``), that factory is bypassed and the
|
|
128
|
+
# directory may not exist yet — ``_uv(... cwd=project)`` would then
|
|
129
|
+
# raise ``FileNotFoundError`` from ``subprocess.run``. Mirror Bub's
|
|
130
|
+
# invariant here so ``agentseek install`` works in a fresh workspace.
|
|
131
|
+
project.mkdir(parents=True, exist_ok=True)
|
|
132
|
+
if (project / "pyproject.toml").is_file():
|
|
133
|
+
return
|
|
134
|
+
bub_cli._uv("init", "--bare", "--name", DEFAULT_PLUGIN_SANDBOX, "--app", cwd=project)
|
|
135
|
+
bub_requirement = bub_cli._build_bub_requirement()
|
|
136
|
+
bub_cli._uv("add", "--active", "--no-sync", *bub_requirement, cwd=project)
|
|
137
|
+
|
|
138
|
+
# Ruff B010 rewrites `setattr(mod, "const", ...)` to assignment; that breaks ty's monkeypatch
|
|
139
|
+
# typing. ``object.__setattr__`` keeps dynamic binding and satisfies both.
|
|
140
|
+
object.__setattr__(bub_cli, "_ensure_project", _ensure_plugin_sandbox)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def apply_agentseek_cli_overrides() -> None:
|
|
144
|
+
"""Patch ``bub.builtin.cli`` before ``BubFramework.create_cli_app`` registers commands.
|
|
145
|
+
|
|
146
|
+
Apply onboarding branding first, then chat channel defaults and install sandbox behavior; all
|
|
147
|
+
target the same module and must run before Typer binds builtin commands.
|
|
148
|
+
"""
|
|
149
|
+
apply_agentseek_onboard_branding()
|
|
150
|
+
apply_agentseek_chat_channel_defaults()
|
|
151
|
+
apply_agentseek_install_project_defaults()
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
__all__ = [
|
|
155
|
+
"AGENTSEEK_ONBOARD_BANNER",
|
|
156
|
+
"AGENTSEEK_ONBOARD_WELCOME",
|
|
157
|
+
"agentseek_version",
|
|
158
|
+
"apply_agentseek_chat_channel_defaults",
|
|
159
|
+
"apply_agentseek_cli_overrides",
|
|
160
|
+
"apply_agentseek_install_project_defaults",
|
|
161
|
+
"apply_agentseek_onboard_branding",
|
|
162
|
+
"resolve_enabled_channels",
|
|
163
|
+
]
|
agentseek/env.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from collections.abc import Mapping, MutableMapping
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
9
|
+
from pydantic_settings.sources import DotEnvSettingsSource, EnvSettingsSource
|
|
10
|
+
|
|
11
|
+
AGENTSEEK_ENV_PREFIX = "AGENTSEEK_"
|
|
12
|
+
BUB_ENV_PREFIX = "BUB_"
|
|
13
|
+
|
|
14
|
+
# Default layout when ``BUB_HOME`` / ``AGENTSEEK_HOME`` are unset: ``cwd / DEFAULT_AGENTSEEK_HOME``.
|
|
15
|
+
DEFAULT_AGENTSEEK_HOME = ".agentseek"
|
|
16
|
+
|
|
17
|
+
# Basename of Bub config under ``BUB_HOME``.
|
|
18
|
+
DEFAULT_AGENTSEEK_CONFIG = "config.yml"
|
|
19
|
+
|
|
20
|
+
# Under ``BUB_HOME`` for ``agentseek install`` when ``BUB_PROJECT`` / ``AGENTSEEK_PROJECT`` are unset.
|
|
21
|
+
# Must match ``uv init --name`` in ``apply_agentseek_install_project_defaults`` (cli.py).
|
|
22
|
+
DEFAULT_PLUGIN_SANDBOX = "agentseek-project"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class _AgentseekAliasProbeSettings(BaseSettings):
|
|
26
|
+
model_config = SettingsConfigDict(
|
|
27
|
+
case_sensitive=True,
|
|
28
|
+
env_file=".env",
|
|
29
|
+
env_file_encoding="utf-8",
|
|
30
|
+
env_ignore_empty=True,
|
|
31
|
+
extra="ignore",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AgentseekSettings(BaseSettings):
|
|
36
|
+
"""Runtime knobs resolved from the AGENTSEEK_* namespace."""
|
|
37
|
+
|
|
38
|
+
model_config = SettingsConfigDict(
|
|
39
|
+
env_prefix=AGENTSEEK_ENV_PREFIX,
|
|
40
|
+
case_sensitive=False,
|
|
41
|
+
env_file=".env",
|
|
42
|
+
env_file_encoding="utf-8",
|
|
43
|
+
env_ignore_empty=True,
|
|
44
|
+
extra="ignore",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Enable local Logfire console rendering for spans/events.
|
|
48
|
+
console: bool = Field(default=False)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_agentseek_settings() -> AgentseekSettings:
|
|
52
|
+
"""Resolve agentseek settings from the current process environment."""
|
|
53
|
+
return AgentseekSettings()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def apply_agentseek_env_aliases(environ: MutableMapping[str, str] | None = None) -> None:
|
|
57
|
+
"""Let AGENTSEEK_* variables act as fallbacks for BUB_* variables.
|
|
58
|
+
|
|
59
|
+
Also applies agentseek defaults for ``BUB_HOME`` (see ``DEFAULT_AGENTSEEK_HOME``) and
|
|
60
|
+
``BUB_PROJECT`` (under that home, see ``DEFAULT_PLUGIN_SANDBOX``) when unset.
|
|
61
|
+
"""
|
|
62
|
+
target_environ = os.environ if environ is None else environ
|
|
63
|
+
for name, value in _collect_agentseek_bub_aliases().items():
|
|
64
|
+
target_environ.setdefault(name, value)
|
|
65
|
+
_apply_agentseek_bub_location_defaults(target_environ)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _apply_agentseek_bub_location_defaults(target_environ: MutableMapping[str, str]) -> None:
|
|
69
|
+
"""Set ``BUB_HOME`` then ``BUB_PROJECT`` only when missing (``setdefault``)."""
|
|
70
|
+
target_environ.setdefault("BUB_HOME", _default_bub_home_for_agentseek())
|
|
71
|
+
bub_home = Path(target_environ["BUB_HOME"]).expanduser()
|
|
72
|
+
plugin_root = bub_home / DEFAULT_PLUGIN_SANDBOX
|
|
73
|
+
target_environ.setdefault("BUB_PROJECT", str(plugin_root))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _default_bub_home_for_agentseek() -> str:
|
|
77
|
+
"""String path Bub uses as ``BUB_HOME`` when the user has not set ``BUB_HOME`` / ``AGENTSEEK_HOME``."""
|
|
78
|
+
return str(default_agentseek_home())
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def agentseek_config_file() -> Path:
|
|
82
|
+
bub_home = Path(os.environ["BUB_HOME"]).expanduser()
|
|
83
|
+
return (bub_home / DEFAULT_AGENTSEEK_CONFIG).resolve()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def default_agentseek_home() -> Path:
|
|
87
|
+
"""Resolved directory for Bub runtime home when ``BUB_HOME`` is unset."""
|
|
88
|
+
return Path.cwd() / DEFAULT_AGENTSEEK_HOME
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _collect_agentseek_bub_aliases() -> dict[str, str]:
|
|
92
|
+
aliases: dict[str, str] = {}
|
|
93
|
+
for env_vars in _iter_agentseek_env_vars():
|
|
94
|
+
aliases.update(_bub_aliases(env_vars))
|
|
95
|
+
return aliases
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _iter_agentseek_env_vars() -> tuple[Mapping[str, str | None], ...]:
|
|
99
|
+
return (
|
|
100
|
+
DotEnvSettingsSource(_AgentseekAliasProbeSettings).env_vars,
|
|
101
|
+
EnvSettingsSource(_AgentseekAliasProbeSettings).env_vars,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _bub_aliases(env_vars: Mapping[str, str | None]) -> dict[str, str]:
|
|
106
|
+
aliases: dict[str, str] = {}
|
|
107
|
+
for name, value in env_vars.items():
|
|
108
|
+
if not name.startswith(AGENTSEEK_ENV_PREFIX) or value is None:
|
|
109
|
+
continue
|
|
110
|
+
|
|
111
|
+
suffix = name.removeprefix(AGENTSEEK_ENV_PREFIX)
|
|
112
|
+
if suffix:
|
|
113
|
+
aliases[f"{BUB_ENV_PREFIX}{suffix}"] = value
|
|
114
|
+
return aliases
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: agentseek
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A database-native Agent Harness for runtime data workflows, powered by Bub
|
|
5
|
+
Keywords: python
|
|
6
|
+
Author-Email: Chojan Shang <psiace@apache.org>
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: Programming Language :: Python
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Project-URL: Repository, https://github.com/ob-labs/agentseek
|
|
15
|
+
Requires-Python: <4.0,>=3.12
|
|
16
|
+
Requires-Dist: bub>=0.3.7
|
|
17
|
+
Requires-Dist: bub-feishu
|
|
18
|
+
Requires-Dist: bub-mcp
|
|
19
|
+
Requires-Dist: agentseek-schedule-sqlalchemy
|
|
20
|
+
Requires-Dist: logfire>=4.33.0
|
|
21
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
22
|
+
Provides-Extra: ag-ui
|
|
23
|
+
Requires-Dist: agentseek-ag-ui; extra == "ag-ui"
|
|
24
|
+
Provides-Extra: cli
|
|
25
|
+
Requires-Dist: agentseek-cli; extra == "cli"
|
|
26
|
+
Provides-Extra: langchain
|
|
27
|
+
Requires-Dist: agentseek-langchain; extra == "langchain"
|
|
28
|
+
Provides-Extra: observability
|
|
29
|
+
Requires-Dist: agentseek-observability; extra == "observability"
|
|
30
|
+
Provides-Extra: oceanbase
|
|
31
|
+
Requires-Dist: agentseek-tapestore-oceanbase; extra == "oceanbase"
|
|
32
|
+
Provides-Extra: context
|
|
33
|
+
Requires-Dist: agentseek-cli; extra == "context"
|
|
34
|
+
Requires-Dist: agentseek-contextseek; extra == "context"
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# agentseek
|
|
38
|
+
|
|
39
|
+
[中文](README.zh.md) | English
|
|
40
|
+
|
|
41
|
+
[](LICENSE)
|
|
42
|
+
[](https://github.com/ob-labs/agentseek/actions/workflows/main.yml?query=branch%3Amain)
|
|
43
|
+
|
|
44
|
+
A database-native Agent Harness, by the [OceanBase](https://en.oceanbase.com/) OSS Team.
|
|
45
|
+
|
|
46
|
+
## What agentseek is
|
|
47
|
+
|
|
48
|
+
agentseek is a database-native Agent Harness for teams that want agent runtime data to become a first-class database workload.
|
|
49
|
+
|
|
50
|
+
It treats the database as the natural place to keep agent context, execution history, tool calls, tasks, feedback, and observability together. The same runtime data can then serve debugging, replay, trajectory comparison, evaluation, analysis, and training workflows without being copied into separate systems or re-ingested later.
|
|
51
|
+
|
|
52
|
+
agentseek packages [Bub](https://github.com/bubbuild/bub) with agentseek defaults, environment aliases, and a project-local runtime layout. Use `agentseek` when you want the Bub runtime model with a project-local `.agentseek` home and `AGENTSEEK_*` configuration.
|
|
53
|
+
|
|
54
|
+
## Why it exists
|
|
55
|
+
|
|
56
|
+
Most agents already prove their value at runtime, but their runtime data is often scattered across JSONL logs, Markdown notes, SQLite files, tracing systems, object storage, and offline pipelines. After the first interaction, that data becomes expensive to query, replay, compare, evaluate, or turn into training material.
|
|
57
|
+
|
|
58
|
+
agentseek starts from a different assumption: context, memory, tasks, tool calls, traces, feedback, and evaluation material should share one durable substrate from the beginning. For agent systems, this makes runtime data reusable. For databases, it opens a direct path to carry intelligent-application workloads instead of only storing final business results.
|
|
59
|
+
|
|
60
|
+
## Quick Start
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
git clone https://github.com/ob-labs/agentseek.git
|
|
64
|
+
cd agentseek
|
|
65
|
+
uv sync
|
|
66
|
+
uv run agentseek --help
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Configure a model, then start a local chat:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
export AGENTSEEK_MODEL=openrouter:free
|
|
73
|
+
export AGENTSEEK_API_KEY=sk-or-v1-your-key
|
|
74
|
+
export AGENTSEEK_API_BASE=https://openrouter.ai/api/v1
|
|
75
|
+
uv run agentseek chat
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`agentseek` is a Bub-compatible distribution entry point. It defaults to `.agentseek` under the current workspace for local config and runtime home. You can also use `uv run bub ...` and Bub plugins directly when you want the upstream CLI or extension namespace.
|
|
79
|
+
|
|
80
|
+
Project-local skills under `.agents/skills` work in local runs because Bub discovers project skills from the workspace. For MCP, `bub-mcp` uses `${BUB_HOME}/mcp.json` by default, which becomes `.agentseek/mcp.json` with agentseek defaults; if you prefer `.agents/mcp.json` in the project root, set `AGENTSEEK_MCP_CONFIG_PATH=.agents/mcp.json`.
|
|
81
|
+
|
|
82
|
+
## Docker Compose
|
|
83
|
+
|
|
84
|
+
If you want to run `agentseek` in a container with the project workspace mounted in, use the bundled compose setup:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
cp .env.example .env
|
|
88
|
+
make compose-up
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
By default, compose will:
|
|
92
|
+
|
|
93
|
+
- mount the current repository into `/workspace`
|
|
94
|
+
- reuse `.agents/skills` and `.agents/mcp.json`
|
|
95
|
+
- persist runtime state under `.agentseek` in the workspace
|
|
96
|
+
|
|
97
|
+
To mount a different host directory as the workspace, set `AGENTSEEK_DOCKER_WORKSPACE`. To override the MCP config source path in containers, set `AGENTSEEK_MCP_CONFIG_PATH`.
|
|
98
|
+
|
|
99
|
+
## Documentation
|
|
100
|
+
|
|
101
|
+
The main documentation describes the built-in agentseek distribution layer:
|
|
102
|
+
|
|
103
|
+
- [Overview](docs/index.md): what agentseek is, where it fits, and how the docs are structured.
|
|
104
|
+
- [Blog intro](docs/blog/index.md): release notes, migrations, and longer-form posts.
|
|
105
|
+
- [Introducing agentseek](docs/blog/introducing-agentseek.md): lineage from bubseek, database-native harness, and Bub/tape context.
|
|
106
|
+
- [Getting started](docs/docs/getting-started.md): a tutorial for running agentseek locally or with Docker Compose.
|
|
107
|
+
- [Configuration](docs/docs/configuration.md): reference for agentseek environment aliases, local runtime paths, and Docker defaults.
|
|
108
|
+
- [Extensions](docs/docs/extensions.md): how to add project instructions, skills, MCP config, and Bub-compatible plugins.
|
|
109
|
+
|
|
110
|
+
Contrib packages document their complete setup in their own README files:
|
|
111
|
+
|
|
112
|
+
- [agentseek-observability](contrib/agentseek-observability/README.md)
|
|
113
|
+
- [agentseek-tapestore-oceanbase](contrib/agentseek-tapestore-oceanbase/README.md)
|
|
114
|
+
- [agentseek-langchain](contrib/agentseek-langchain/README.md)
|
|
115
|
+
- [agentseek-schedule-sqlalchemy](contrib/agentseek-schedule-sqlalchemy/README.md)
|
|
116
|
+
|
|
117
|
+
## How it works
|
|
118
|
+
|
|
119
|
+
- **Bub as the runtime layer** — [Bub](https://github.com/bubbuild/bub) provides the CLI, hook-first turn pipeline, tape context, skills, plugins, and channel model. agentseek uses Bub as the default governance layer, not as the product boundary.
|
|
120
|
+
- **Project-local defaults** — `.agentseek` is the default runtime home, and `agentseek-project` is the default plugin sandbox used by `agentseek install`.
|
|
121
|
+
- **Environment aliases** — `AGENTSEEK_*` values act as fallbacks for matching `BUB_*` values, so agentseek projects can use their own naming namespace while staying Bub-compatible.
|
|
122
|
+
- **Open authoring model** — `AGENTS.md`, project-local skills, bundled skills, and MCP config are first-class parts of the authoring and extension workflow.
|
|
123
|
+
- **Contrib extension path** — database storage, LangChain routing, persistent scheduling, and other larger integrations live under `contrib/` and keep their full usage docs there.
|
|
124
|
+
|
|
125
|
+
For a good default experience from local development to larger deployments, we recommend [OceanBase seekdb](https://github.com/oceanbase/seekdb) and OceanBase.
|
|
126
|
+
|
|
127
|
+
## Development
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
make install
|
|
131
|
+
make check
|
|
132
|
+
make test
|
|
133
|
+
make docs-test
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Contrib package README files document their package-specific checks.
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
[Apache-2.0](LICENSE)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
agentseek-0.0.1.dist-info/METADATA,sha256=K8z8oFxjpvnn5rEgpu_mlNbtKKYEssQ26KGkls4Wg8s,7226
|
|
2
|
+
agentseek-0.0.1.dist-info/WHEEL,sha256=Z36eTX6lG3PITRleSd5hAZHCcz52yg3c0JQVxKBbLW0,90
|
|
3
|
+
agentseek-0.0.1.dist-info/entry_points.txt,sha256=Pe3zH1Oj0_hlYlQCt3L0QBokSFrqoPQApITGcTjNTnE,69
|
|
4
|
+
agentseek-0.0.1.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
5
|
+
agentseek/__init__.py,sha256=P0S1YwSP-JH8_wGk91HpMqLexjyBqPDID-O4MLJVHo8,50
|
|
6
|
+
agentseek/__main__.py,sha256=YucCqjGqFT_cQHPU5y-aMxJ0lwKiogH1To0AktZwsyE,1770
|
|
7
|
+
agentseek/cli.py,sha256=HPYh50XvE-9qcY-3CXyMCItbWSqlfhu1T0fYVKW4WL0,6353
|
|
8
|
+
agentseek/env.py,sha256=Gvk3Y4CqdDEh33WD2irrvesAsKRT_OD8h5KDdnTNvGk,4016
|
|
9
|
+
skills/README.md,sha256=EoAiMt-OsUAYIY1is243CennUFsRc8vmqg3xUZzzg58,198
|
|
10
|
+
skills/friendly-python/SKILL.md,sha256=ro5fQad7ZdeItMVS8NiY4U30cFlykQWIQiw8mlf2Hzo,2419
|
|
11
|
+
skills/friendly-python/agents/openai.yaml,sha256=iFKEMz2JYyu3fP7hn_rbHM_pXvP4uqipNHJGhrHB0w0,265
|
|
12
|
+
skills/friendly-python/references/api-design.md,sha256=A54-_wlRS8EKjgpshUrhqXNhP4OLNBjMDzQQFncyq7c,1467
|
|
13
|
+
skills/friendly-python/references/cli-argparse.md,sha256=I34r4seo4CGvcgL3EMzSaPhWxQP5AO3SKZougjgksUM,1116
|
|
14
|
+
skills/friendly-python/references/error-handling.md,sha256=f2Kfn0L7TJhgAGv09RlV3xvDeRtyDsDO7mQsDEyh-o4,1069
|
|
15
|
+
skills/friendly-python/references/extension-architecture.md,sha256=A3fsw1GGF-9vcYvaWN3QbyXOkH7_dKKBH9UR0o0znCo,1516
|
|
16
|
+
skills/friendly-python/references/oop-design.md,sha256=3BmNLE-zl8Vqkm8fL7s4BbvvvbGs2g-BkXdVY0BrqPU,1564
|
|
17
|
+
skills/friendly-python/references/portability-pythonic.md,sha256=5I7F_CIvCRkVOT4mNVKLYvX5SiPQUrQUCcesluCfCIo,1409
|
|
18
|
+
skills/friendly-python/references/principles.md,sha256=iBXvE3jXUeJnjKoaEPs61lssQJ8zu1zIMKj1LiLrOHk,1511
|
|
19
|
+
skills/friendly-python/references/reuse-composition.md,sha256=Oi8Emwaso_0eI7U3pAPVpBTa7jbvu2MDIJ3hezFczy0,1008
|
|
20
|
+
skills/friendly-python/references/review-checklist.md,sha256=Cc-M6sHzdWXIHPB3QpT3CeMb3ZCSsd0o9BSC8QYX4AE,1455
|
|
21
|
+
skills/piglet/SKILL.md,sha256=8n8nZOSFQ57C5aAsEB_6i6tdXRCtyf2qYbkjPMR_TzI,3249
|
|
22
|
+
skills/piglet/agents/openai.yaml,sha256=GPIPurbYURjpdZc2ERjzOUYz2jtm5-T-_QWaFMm2Z6c,269
|
|
23
|
+
skills/piglet/references/decorators.md,sha256=erB7wogod2XC8QoJHVItrWjVA_oe0-rMz-TA7BzN41A,1150
|
|
24
|
+
skills/piglet/references/edge-cases.md,sha256=hANzy_fNw2Ty9MyQirP8nGZcErgZ5g1ndAGhqsthW7I,696
|
|
25
|
+
skills/piglet/references/exceptions-handling.md,sha256=D1Me2j9Z3aQv1AblL2MmSo3azAeWKLr0O6Ek8ykbhiM,1548
|
|
26
|
+
skills/piglet/references/functions-and-returns.md,sha256=M7usUUz64h44h_TqAz2LtZOHbZiLmOyMk1nwyt-VYO8,1307
|
|
27
|
+
skills/piglet/references/if-else-and-branches.md,sha256=rjw2HUiE49l0ee5hm94_t42Xp22NetNObf68Zt8P3jQ,1194
|
|
28
|
+
skills/piglet/references/imports-and-structure.md,sha256=eNaH-3EKKojvXoRv62-ZIkRFCVeCT24YEHRuSnvXYxY,831
|
|
29
|
+
skills/piglet/references/loops-and-iteration.md,sha256=vEAYyp10_Y1LunGmvkoe19THvi5Wff3XTTyb36XmNNs,853
|
|
30
|
+
skills/piglet/references/rules-and-file-io.md,sha256=8xTX7-he6HyT07uZrtp9Bo3wa45N6GEbMS9WIDu_PMk,2071
|
|
31
|
+
skills/piglet/references/solid-python.md,sha256=RizU1RbvbYAjE8o0MIt2Zh7NQKlKjUM4UH5Qu4gH_no,1604
|
|
32
|
+
skills/piglet/references/values-and-containers.md,sha256=uJeuKH1q4FBbpDx310GDpZnhDQJZCqZQUer54P0aj_c,1413
|
|
33
|
+
skills/piglet/references/variables-and-naming.md,sha256=3tKV9jZKsWDxyQSvydQhjoipoCFa4qpciK6B9txFqks,1181
|
|
34
|
+
skills/piglet/references/walrus-operator.md,sha256=HeLbmAgQZWvhnh7u2gpkoKKEFlN4IdpBqm2SlJBnzNw,1139
|
|
35
|
+
skills/plugin-creator/SKILL.md,sha256=SGchLmvBjG7y7MBvowcQy0oHV7m-LzrXmXyjvW_kTjI,13117
|
|
36
|
+
agentseek-0.0.1.dist-info/RECORD,,
|