-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathsetup.py
More file actions
249 lines (223 loc) · 10.8 KB
/
Copy pathsetup.py
File metadata and controls
249 lines (223 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
"""
Setup configuration for CIRIS Agent.
This enables pip-installable distribution with optional GUI bundling.
The CLI command 'ciris-agent' wraps the existing main.py Click interface.
Platform-specific wheels:
When a CIRIS Desktop JAR is present in ciris_engine/desktop_app/,
the wheel is tagged with the matching platform (e.g., macosx_11_0_arm64).
When no JAR is present, a pure-Python py3-none-any wheel is produced
for headless server deployments.
Localization:
Localization JSON files (29 languages + manifest) live at
``ciris_engine/data/localized/*.json`` — git-tracked, packaged via
``package_data`` below. They were previously authored at
``localization/*.json`` (gitignored copy at the package path) and a
custom ``build_py`` step copied them in at wheel-build time. That
produced sign-vs-install drift in CI (``stage_runtime`` ran before the
copy step, so the registered manifest dropped 30 .json files; CIRISAgent#744).
In 2.8.8 the source-of-truth moved into the package directory; the
``build_py`` override is no longer needed.
"""
from pathlib import Path
from setuptools import find_packages, setup
try:
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
except ImportError:
_bdist_wheel = None
# Map Compose Desktop JAR platform suffixes to PEP 427 wheel platform tags
_JAR_PLATFORM_MAP = {
"macos-arm64": "macosx_11_0_arm64",
"macos-x64": "macosx_10_15_x86_64",
"linux-x64": "manylinux2014_x86_64",
"windows-x64": "win_amd64",
}
def _detect_host_wheel_tag():
"""Fallback: derive a PEP 427 platform tag from the current interpreter host.
Used when a bundled JRE is present but no JAR filename is available to
imply the target platform.
"""
import platform
import sys
machine = platform.machine().lower()
if sys.platform == "darwin":
return "macosx_11_0_arm64" if machine in {"arm64", "aarch64"} else "macosx_10_15_x86_64"
if sys.platform.startswith("linux"):
return "manylinux2014_x86_64" if machine in {"x86_64", "amd64"} else None
if sys.platform == "win32":
return "win_amd64" if machine in {"amd64", "x86_64"} else None
return None
def _detect_jar_platform():
"""Detect platform from the bundled JAR in ciris_engine/desktop_app/.
NOTE: JRE bundling was removed to keep wheel size under PyPI's 100MB limit.
Platform detection is now based solely on the JAR filename.
"""
desktop_dir = Path(__file__).parent / "ciris_engine" / "desktop_app"
if not desktop_dir.exists():
return None
for jar in desktop_dir.glob("CIRIS-*.jar"):
# JAR names: CIRIS-macos-arm64-2.0.0.jar, CIRIS-linux-x64-2.0.0.jar, etc.
stem = jar.stem # e.g. "CIRIS-macos-arm64-2.0.0"
for jar_suffix, wheel_tag in _JAR_PLATFORM_MAP.items():
if jar_suffix in stem:
return wheel_tag
return None
if _bdist_wheel is not None:
class _PlatformBdistWheel(_bdist_wheel):
"""Override bdist_wheel to set platform tag based on bundled JAR."""
def finalize_options(self):
super().finalize_options()
self._detected_platform = _detect_jar_platform()
if self._detected_platform:
self.root_is_pure = False
def get_tag(self):
if self._detected_platform:
return "py3", "none", self._detected_platform
return super().get_tag()
_cmdclass = {"bdist_wheel": _PlatformBdistWheel}
else:
_cmdclass = {}
# Read the README for long description
this_directory = Path(__file__).parent
long_description = (this_directory / "README.md").read_text(encoding="utf-8")
# Read version from constants.py
version = "1.6.2" # Will be updated by bump_version.py
try:
with open("ciris_engine/constants.py") as f:
for line in f:
if line.startswith("CIRIS_VERSION"):
version = line.split('"')[1]
# Strip "-stable" or other suffixes for PEP 440 compliance
version = version.split("-")[0]
break
except Exception:
pass # Fall back to hardcoded version if constants.py is not readable
# Read requirements. Explicit utf-8 — comments contain non-ASCII (⚠️, →,
# release notes from upstream releases) and the Windows wheel build runs
# under cp1252 by default, which UnicodeDecodeError's on those bytes.
requirements = []
with open("requirements.txt", encoding="utf-8") as f:
requirements = [line.strip() for line in f if line.strip() and not line.startswith("#")]
# Read dev requirements
dev_requirements = []
try:
with open("requirements-dev.txt", encoding="utf-8") as f:
dev_requirements = [line.strip() for line in f if line.strip() and not line.startswith("#")]
except FileNotFoundError:
pass
setup(
name="ciris-agent",
version=version,
cmdclass=_cmdclass,
description="CIRIS: Ethical AI Agent with Consensual Evolution Protocol",
long_description=long_description,
long_description_content_type="text/markdown",
author="Eric Moore",
author_email="eric@ciris.ai",
url="https://github.com/CIRISAI/CIRISAgent",
packages=find_packages(exclude=["tests", "tests.*", "docs", "tools.test_*"]),
py_modules=["main"], # Include main.py at root level
include_package_data=True, # CRITICAL - includes non-Python files from MANIFEST.in
package_data={
"ciris_engine.data": [
"localized/*.json", # Backend localization files (copied from /localization/)
"localized/*.txt", # Localized ACCORD + comprehensive guide text files (guides
# migrated from .md → .txt in 2.8.5 alongside the repo-root
# and docs/ consolidation; staging script can now use a
# clean .md=devnotes denylist)
"agent_experience.txt", # Agent self-help / introspection content (was at
# docs/agent_experience.md pre-2.8.5; CWD-relative
# reader broke on installs)
"geo/cities.db", # GeoNames cities database for location typeahead
],
"ciris_engine.config": [
"*.json", # Pricing and configuration data
],
"ciris_engine.logic.dma": [
"prompts/*.yml", # DMA prompt templates (English)
"prompts/localized/*/*.yml", # Localized DMA prompt templates
],
"ciris_engine.logic.conscience": [
# Same shape as DMA prompts above. The conscience system reads
# entropy/coherence/optimization_veto/epistemic_humility prompt
# templates from these YML files at runtime; missing them on a
# wheel install means the conscience falls back to inline strings
# (silent degradation). Added in 2.8.5 alongside the canonical
# staging work — staging includes them, wheel must too, or the
# runtime walk hash diverges from the signed manifest.
"prompts/*.yml",
"prompts/localized/*/*.yml",
],
"ciris_engine.logic.persistence": [
"migrations/sqlite/*.sql", # SQLite database migrations
"migrations/postgres/*.sql", # PostgreSQL database migrations
],
"ciris_engine.logic.accord": [
"bip39_english.txt", # BIP39 wordlist used by accord/extractor.py
# for mnemonic generation. Load-bearing —
# extractor.py:49 reads from package dir
# via Path(__file__).parent. Wasn't shipped
# in 2.8.4 wheels (extractor fell through
# to /app/tools/security/bip39_english.txt
# which only exists in docker, breaks elsewhere).
],
"ciris_engine": [
"ciris_templates/*.yaml", # Bundled agent identity templates
"desktop_app/*.jar", # CIRIS Desktop app (Kotlin Compose)
# NOTE: JRE no longer bundled to keep wheel under PyPI's 100MB limit.
# Users must have Java 17+ installed; CLI provides install instructions.
],
},
entry_points={
"console_scripts": [
# ONE command. `ciris-server` and `ciris-desktop` belong to the
# ciris-server wheel (the node): the desktop client spawns
# `ciris-server --home ... --key-id ...` and fails fast when that
# starts an agent instead of the node. This package used to install
# both names too, so whichever distribution pip wrote last won --
# and ciris-agent depends on ciris-server, so ours won, and the
# client's node spawn hit Click's unknown-argument error on --home.
# The headless brain is `ciris-agent --server`; the desktop launcher
# is a bare `ciris-agent`.
"ciris-agent=ciris_engine.cli:main", # Desktop app (default) or --server
],
# Adapter discovery entry points - eliminates hardcoded KNOWN_MODULAR_SERVICES list
# Each entry point maps adapter_name -> module path for manifest loading
"ciris.adapters": [
"ciris_hosted_tools=ciris_adapters.ciris_hosted_tools",
"ciris_verify=ciris_adapters.ciris_verify",
"external_data_sql=ciris_adapters.external_data_sql",
"home_assistant=ciris_adapters.home_assistant",
"mcp_client=ciris_adapters.mcp_client",
"mcp_common=ciris_adapters.mcp_common",
"mcp_server=ciris_adapters.mcp_server",
"mock_llm=ciris_adapters.mock_llm",
"navigation=ciris_adapters.navigation",
"reddit=ciris_adapters.reddit",
"sample_adapter=ciris_adapters.sample_adapter",
"weather=ciris_adapters.weather",
],
},
install_requires=requirements,
extras_require={
"dev": dev_requirements,
},
python_requires=">=3.10",
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: GNU Affero General Public License v3",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Topic :: Software Development :: Libraries :: Application Frameworks",
],
keywords="ai agent ethical-ai autonomous-agent discord-bot api-server",
project_urls={
"Bug Reports": "https://github.com/CIRISAI/CIRISAgent/issues",
"Source": "https://github.com/CIRISAI/CIRISAgent",
"Documentation": "https://github.com/CIRISAI/CIRISAgent/tree/main/docs",
},
)