-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAgentSuiteLocal.spec
More file actions
188 lines (179 loc) · 5.68 KB
/
Copy pathAgentSuiteLocal.spec
File metadata and controls
188 lines (179 loc) · 5.68 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
# -*- mode: python ; coding: utf-8 -*-
#
# PyInstaller spec for AgentSuiteLocal.
#
# Build:
# Windows: pyinstaller AgentSuiteLocal.spec
# macOS: pyinstaller AgentSuiteLocal.spec
#
# Output: dist/AgentSuiteLocal/ (one-dir, faster cold start than one-file)
#
# The frontend must be built before running PyInstaller:
# cd web && npm ci && npm run build
#
# --windowed / --noconsole suppresses the terminal on Windows and macOS.
# On macOS this also creates a proper .app bundle in dist/.
import sys
from pathlib import Path
from PyInstaller.utils.hooks import collect_all
ROOT = Path(SPECPATH)
WEB_DIST = ROOT / "web" / "dist"
block_cipher = None
# Collect all agentsuite code + data (jinja2 prompts, md templates, etc.)
_as_datas, _as_binaries, _as_hiddenimports = collect_all("agentsuite")
a = Analysis(
[str(ROOT / "launcher.py")],
pathex=[str(ROOT)],
binaries=_as_binaries,
datas=[
# Bundle the pre-built frontend; accessible at sys._MEIPASS/web/dist at runtime.
(str(WEB_DIST), "web/dist"),
] + _as_datas,
hiddenimports=_as_hiddenimports + [
# uvicorn internals not always auto-detected
"uvicorn.lifespan.on",
"uvicorn.lifespan.off",
"uvicorn.protocols.http.auto",
"uvicorn.protocols.http.h11_impl",
"uvicorn.protocols.http.httptools_impl",
"uvicorn.protocols.websockets.auto",
"uvicorn.protocols.websockets.websockets_impl",
"uvicorn.protocols.websockets.wsproto_impl",
"uvicorn.loops.auto",
"uvicorn.loops.asyncio",
"uvicorn.logging",
# FastAPI / Starlette internals
"starlette.routing",
"starlette.middleware.cors",
"starlette.staticfiles",
"starlette.responses",
# SSE
"sse_starlette",
"sse_starlette.sse",
# psutil platform modules
"psutil._pslinux",
"psutil._pswindows",
"psutil._psosx",
# httpx transport
"httpx._transports.default",
"httpx._transports.asgi",
# email / multipart (FastAPI dependency)
"email.mime.multipart",
"email.mime.text",
"multipart",
"python_multipart",
# pydantic v2
"pydantic.deprecated.class_validators",
"pydantic_core",
# agentsuitelocal dynamic imports
"agentsuite.pipeline.orchestrator",
"agentsuite.pipeline.schema",
"agentsuite.kernel.base_agent",
"agentsuite.llm.ollama",
"agentsuite.llm.resolver",
# Jinja2 (agentsuite prompt templates)
"jinja2",
"jinja2.ext",
"jinja2.loaders",
"markupsafe",
# agentsuite runtime deps
"tenacity",
"anthropic",
"ollama",
"openai",
"mcp",
# S-2: keyring — OS keychain for API key storage
"keyring",
"keyring.backends",
"keyring.backends.Windows",
"keyring.backends.macOS",
"keyring.backends.SecretService",
"keyring.backends.null",
# reportlab — PDF export (pure Python, no native GTK/cairo/pango needed)
"reportlab",
"reportlab.platypus",
"reportlab.lib",
"reportlab.lib.pagesizes",
"reportlab.lib.styles",
"reportlab.lib.units",
"reportlab.pdfgen",
"reportlab.pdfbase",
"reportlab.pdfbase.ttfonts",
"reportlab.pdfbase.pdfmetrics",
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[
# Keep the bundle lean — test frameworks not needed at runtime
"pytest",
"pytest_asyncio",
"playwright",
"IPython",
"jupyter",
"notebook",
"tkinter",
],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name="AgentSuiteLocal",
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=False,
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=str(ROOT / "agentsuitelocal" / "assets" / "icon.ico"),
# N-2: Per-Monitor DPI v2 awareness manifest — crisp on HiDPI / multi-monitor.
# The manifest also declares Windows 10/11 compatibility and long-path support.
manifest=str(ROOT / "agentsuitelocal" / "assets" / "AgentSuiteLocal.manifest")
if sys.platform == "win32" else None,
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=False,
upx_exclude=[],
name="AgentSuiteLocal",
)
# macOS: wrap in a .app bundle
if sys.platform == "darwin":
# M-6: macOS requires .icns (not .ico). Generate icon.icns from brand assets
# on macOS using: python scripts/generate_icns.py (requires Pillow + iconutil)
_mac_icon = ROOT / "agentsuitelocal" / "assets" / "icon.icns"
if not _mac_icon.exists():
_mac_icon = ROOT / "agentsuitelocal" / "assets" / "icon.ico" # fallback for CI
# m-4: derive version from __version__.py instead of hardcoding
import sys as _sys
_sys.path.insert(0, str(ROOT))
try:
from agentsuitelocal.__version__ import __version__ as _APP_VERSION
except ImportError:
_APP_VERSION = "0.7.0"
app = BUNDLE(
coll,
name="AgentSuiteLocal.app",
icon=str(_mac_icon),
bundle_identifier="com.scottconverse.agentsuitelocal",
info_plist={
"CFBundleShortVersionString": _APP_VERSION,
"CFBundleName": "AgentSuiteLocal",
"NSHighResolutionCapable": True,
"LSUIElement": False, # Show in Dock
},
)