kimi-agent-module-api 1.0.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.
- kimi_agent_module_api/__init__.py +175 -0
- kimi_agent_module_api/contracts.py +1127 -0
- kimi_agent_module_api/events.py +140 -0
- kimi_agent_module_api/images.py +34 -0
- kimi_agent_module_api/py.typed +1 -0
- kimi_agent_module_api/settings.py +33 -0
- kimi_agent_module_api/testing.py +1036 -0
- kimi_agent_module_api/tools.py +63 -0
- kimi_agent_module_api/trust.py +36 -0
- kimi_agent_module_api-1.0.0.dist-info/METADATA +51 -0
- kimi_agent_module_api-1.0.0.dist-info/RECORD +14 -0
- kimi_agent_module_api-1.0.0.dist-info/WHEEL +5 -0
- kimi_agent_module_api-1.0.0.dist-info/licenses/LICENSE +21 -0
- kimi_agent_module_api-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""Stable public contracts for trusted, installed assistant modules."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Callable, Mapping, Sequence
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any, Protocol, TypeVar
|
|
9
|
+
|
|
10
|
+
from pydantic_settings import BaseSettings
|
|
11
|
+
|
|
12
|
+
from kimi_agent_module_api.contracts import (
|
|
13
|
+
ConfigSnapshot,
|
|
14
|
+
RoleSnapshot,
|
|
15
|
+
render_guild_settings,
|
|
16
|
+
DiscordActions,
|
|
17
|
+
EventBus,
|
|
18
|
+
GuildSettings,
|
|
19
|
+
GuildSettingsSchema,
|
|
20
|
+
HealthReporter,
|
|
21
|
+
InviteSnapshot,
|
|
22
|
+
InteractionRouter,
|
|
23
|
+
ModuleHttp,
|
|
24
|
+
ModulePermissions,
|
|
25
|
+
ModuleStorage,
|
|
26
|
+
ScopedModuleMigration,
|
|
27
|
+
ProposalActor,
|
|
28
|
+
ProposalError,
|
|
29
|
+
ProposalRef,
|
|
30
|
+
ProposalService,
|
|
31
|
+
ProposalState,
|
|
32
|
+
Scheduler,
|
|
33
|
+
ServiceDeclaration,
|
|
34
|
+
ServiceRegistry,
|
|
35
|
+
ServiceRequirement,
|
|
36
|
+
TrustLookup,
|
|
37
|
+
)
|
|
38
|
+
from kimi_agent_module_api.settings import ModuleSetting, ModuleSettingsDefinition
|
|
39
|
+
from kimi_agent_module_api.tools import (
|
|
40
|
+
ModuleToolContext,
|
|
41
|
+
ModuleToolHandler,
|
|
42
|
+
ModuleToolRegistry,
|
|
43
|
+
)
|
|
44
|
+
from kimi_agent_module_api.trust import TrustTier
|
|
45
|
+
|
|
46
|
+
MODULE_API_VERSION = 1
|
|
47
|
+
MODULE_ENTRYPOINT_GROUP = "kimi_agent.modules"
|
|
48
|
+
# Capabilities every compatible host advertises regardless of configuration.
|
|
49
|
+
BASELINE_CAPABILITIES: frozenset[str] = frozenset({"discord.history.v1", "proposals.v2"})
|
|
50
|
+
|
|
51
|
+
_SettingsT = TypeVar("_SettingsT", bound=BaseSettings)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@dataclass(frozen=True)
|
|
55
|
+
class ModuleCapabilities:
|
|
56
|
+
available: frozenset[str]
|
|
57
|
+
members_intent: bool
|
|
58
|
+
message_content_intent: bool
|
|
59
|
+
|
|
60
|
+
def require(self, name: str) -> None:
|
|
61
|
+
if name not in self.available:
|
|
62
|
+
raise RuntimeError(f"the host does not provide required capability {name!r}")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class AppModule(Protocol):
|
|
66
|
+
scoped_migrations: Sequence[ScopedModuleMigration]
|
|
67
|
+
|
|
68
|
+
async def start(self, ctx: ModuleRuntimeContext) -> None: ...
|
|
69
|
+
|
|
70
|
+
async def close(self) -> None: ...
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True)
|
|
74
|
+
class ModuleSpec:
|
|
75
|
+
name: str
|
|
76
|
+
version: str
|
|
77
|
+
create: Callable[[ModuleLoadContext], AppModule]
|
|
78
|
+
api_version: int = MODULE_API_VERSION
|
|
79
|
+
dependencies: tuple[str, ...] = ()
|
|
80
|
+
settings: ModuleSettingsDefinition | None = None
|
|
81
|
+
requires_capabilities: tuple[str, ...] = ()
|
|
82
|
+
activation_capabilities: tuple[str, ...] = ()
|
|
83
|
+
permissions: ModulePermissions = field(default_factory=ModulePermissions)
|
|
84
|
+
guild_settings: GuildSettingsSchema | None = None
|
|
85
|
+
provides: tuple[ServiceDeclaration, ...] = ()
|
|
86
|
+
consumes: tuple[ServiceRequirement, ...] = ()
|
|
87
|
+
table_aliases: Mapping[str, str] = field(default_factory=dict)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@dataclass(frozen=True)
|
|
91
|
+
class ModuleLoadContext:
|
|
92
|
+
"""What ``ModuleSpec.create`` receives.
|
|
93
|
+
|
|
94
|
+
``create()`` is pure wiring: read prepared settings, register LLM tools,
|
|
95
|
+
construct the module object. No migration has run and no dependency has
|
|
96
|
+
started, so nothing here reaches storage, services, or Discord; that work
|
|
97
|
+
belongs in ``start()``. The tool registry is sealed once loading finishes,
|
|
98
|
+
so tools cannot be registered later from ``start()`` either.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
capabilities: ModuleCapabilities
|
|
102
|
+
registry: ModuleToolRegistry
|
|
103
|
+
module_settings: BaseSettings | None
|
|
104
|
+
# Host sinks behind the two convenience methods below. Tests build a
|
|
105
|
+
# context with ``kimi_agent_module_api.testing.load_context``.
|
|
106
|
+
label_sink: Callable[[Mapping[str, str]], None]
|
|
107
|
+
surface_sink: Callable[[str, Sequence[str]], None]
|
|
108
|
+
|
|
109
|
+
def settings_for(self, settings_type: type[_SettingsT]) -> _SettingsT:
|
|
110
|
+
if self.module_settings is None or not isinstance(self.module_settings, settings_type):
|
|
111
|
+
raise TypeError(f"prepared module settings are not {settings_type.__name__}")
|
|
112
|
+
return self.module_settings
|
|
113
|
+
|
|
114
|
+
def register_tool_labels(self, labels: Mapping[str, str]) -> None:
|
|
115
|
+
"""Gerund phrases shown while a tool runs, e.g. ``{"give_kudos": "Giving kudos"}``."""
|
|
116
|
+
self.label_sink(labels)
|
|
117
|
+
|
|
118
|
+
def declare_surface_tools(self, surface: str, names: Sequence[str]) -> None:
|
|
119
|
+
"""Declare which tools belong to a named evaluation surface."""
|
|
120
|
+
self.surface_sink(surface, names)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@dataclass(frozen=True)
|
|
124
|
+
class ModuleRuntimeContext:
|
|
125
|
+
"""Runtime ports supplied to one module after it has been loaded."""
|
|
126
|
+
|
|
127
|
+
module_name: str
|
|
128
|
+
is_guild_active: Callable[[int], bool]
|
|
129
|
+
current_config_dir: Callable[[], Path]
|
|
130
|
+
capabilities: ModuleCapabilities
|
|
131
|
+
events: EventBus
|
|
132
|
+
scheduler: Scheduler
|
|
133
|
+
storage: ModuleStorage
|
|
134
|
+
health: HealthReporter
|
|
135
|
+
discord: DiscordActions
|
|
136
|
+
interactions: InteractionRouter
|
|
137
|
+
http: ModuleHttp
|
|
138
|
+
services: ServiceRegistry
|
|
139
|
+
trust: TrustLookup
|
|
140
|
+
guild_settings: GuildSettings | None = None
|
|
141
|
+
proposals: ProposalService | None = None
|
|
142
|
+
raw_bot: Any = None
|
|
143
|
+
raw_storage: Any = None
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
__all__ = [
|
|
147
|
+
"BASELINE_CAPABILITIES",
|
|
148
|
+
"MODULE_API_VERSION",
|
|
149
|
+
"MODULE_ENTRYPOINT_GROUP",
|
|
150
|
+
"AppModule",
|
|
151
|
+
"ConfigSnapshot",
|
|
152
|
+
"GuildSettingsSchema",
|
|
153
|
+
"InviteSnapshot",
|
|
154
|
+
"ModuleCapabilities",
|
|
155
|
+
"ModuleLoadContext",
|
|
156
|
+
"ModulePermissions",
|
|
157
|
+
"ModuleRuntimeContext",
|
|
158
|
+
"ModuleSetting",
|
|
159
|
+
"ModuleSettingsDefinition",
|
|
160
|
+
"ModuleSpec",
|
|
161
|
+
"ModuleToolContext",
|
|
162
|
+
"ModuleToolHandler",
|
|
163
|
+
"ModuleToolRegistry",
|
|
164
|
+
"ProposalActor",
|
|
165
|
+
"ProposalError",
|
|
166
|
+
"ProposalRef",
|
|
167
|
+
"ProposalService",
|
|
168
|
+
"ProposalState",
|
|
169
|
+
"RoleSnapshot",
|
|
170
|
+
"ScopedModuleMigration",
|
|
171
|
+
"ServiceDeclaration",
|
|
172
|
+
"ServiceRequirement",
|
|
173
|
+
"TrustTier",
|
|
174
|
+
"render_guild_settings",
|
|
175
|
+
]
|