mirror of
https://github.com/block/buzz.git
synced 2026-11-08 18:31:56 +00:00
Checkpoint Pulse canvas, content sizing, and Chief briefings prototype
Signed-off-by: Arjun Mahanti <arjun@squareup.com>
This commit is contained in:
93
scripts/chief-accumulator.py
Normal file
93
scripts/chief-accumulator.py
Normal file
@@ -0,0 +1,93 @@
|
||||
"""Local prototype bootstrap. Source, database and build outputs stay gitignored."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
REVISION = '5d12db76c0b6b59c686c5a9aaf9d2367bd73f7ad'
|
||||
URL = 'https://buzz.block.builderlab.xyz/git/478bb5a31222ea2b28a3d1afb8b1d598940628f19c2a87efc3c4b822299eeec6/intelligence-workbench'
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--source-dir', type=Path, help='Use an existing clean checkout of the pinned revision')
|
||||
parser.add_argument('--build-only', action='store_true')
|
||||
parser.add_argument('--relay', default='wss://buzz.block.builderlab.xyz')
|
||||
args = parser.parse_args()
|
||||
os.umask(0o077)
|
||||
base = ROOT / '.cache/chief'
|
||||
base.mkdir(parents=True, exist_ok=True)
|
||||
source = args.source_dir.resolve() if args.source_dir else base / 'source'
|
||||
identity = None
|
||||
|
||||
def load_identity():
|
||||
nonlocal identity
|
||||
if identity:
|
||||
return identity
|
||||
result = subprocess.run(['/usr/bin/security', 'find-generic-password', '-s', 'buzz-desktop', '-a', 'secrets', '-w'], capture_output=True, text=True)
|
||||
if result.returncode:
|
||||
sys.exit('Could not access the existing Buzz identity in Keychain.')
|
||||
try:
|
||||
identity = json.loads(result.stdout).get('identity')
|
||||
except (ValueError, AttributeError):
|
||||
sys.exit('Unexpected Buzz Keychain format.')
|
||||
if not isinstance(identity, str) or not identity.strip():
|
||||
sys.exit('No Buzz identity found in Keychain.')
|
||||
identity = identity.strip()
|
||||
return identity
|
||||
|
||||
if not source.exists():
|
||||
helper = ROOT / 'target/release/git-credential-nostr'
|
||||
if not helper.is_file():
|
||||
subprocess.run([str(ROOT / 'bin/cargo'), 'build', '--release', '-p', 'git-credential-nostr'], cwd=ROOT, check=True)
|
||||
environment = os.environ.copy()
|
||||
environment.update(NOSTR_PRIVATE_KEY=load_identity(), GIT_TERMINAL_PROMPT='0')
|
||||
subprocess.run(['git', '-c', 'credential.helper=', '-c', f'credential.helper={helper}', '-c', 'credential.useHttpPath=true', 'clone', '--single-branch', '--branch', 'main', URL, str(source)], env=environment, check=True, timeout=180)
|
||||
subprocess.run(['git', '-C', str(source), 'checkout', '--detach', REVISION], check=True)
|
||||
revision = subprocess.check_output(['git', '-C', str(source), 'rev-parse', 'HEAD'], text=True).strip()
|
||||
dirty = subprocess.check_output(['git', '-C', str(source), 'status', '--porcelain', '--untracked-files=no'], text=True).strip()
|
||||
if revision != REVISION or dirty:
|
||||
sys.exit(f'Expected a clean Accumulator checkout at {REVISION}. No files were reset.')
|
||||
target = base / 'target'
|
||||
subprocess.run([str(ROOT / 'bin/cargo'), 'build', '--locked', '--manifest-path', str(source / 'Cargo.toml'), '--target-dir', str(target), '-p', 'buzz-accumulator'], cwd=source, check=True)
|
||||
if args.build_only:
|
||||
return
|
||||
key = load_identity()
|
||||
# Separate local databases for every identity/relay. The directory is an opaque
|
||||
# hash; neither the key nor a key file is persisted in the source checkout.
|
||||
scope = hashlib.sha256((args.relay.rstrip('/') + '\0' + key).encode()).hexdigest()
|
||||
data = base / 'data' / scope
|
||||
data.mkdir(parents=True, exist_ok=True)
|
||||
environment = os.environ.copy()
|
||||
for name in list(environment):
|
||||
if name.startswith(('BUZZ_', 'NOSTR_')):
|
||||
del environment[name]
|
||||
environment['BUZZ_FOLD_RUNNER_BIN'] = str(ROOT / 'scripts/chief-model-runner.py')
|
||||
with tempfile.TemporaryDirectory(prefix='buzz-chief-identity-') as keydir:
|
||||
keyfile = Path(keydir) / 'identity.key'
|
||||
keyfile.write_text(key)
|
||||
keyfile.chmod(0o600)
|
||||
print('Starting private briefings on 127.0.0.1:4640 using your Buzz identity.', flush=True)
|
||||
print('Open Home → Saved briefings. Accumulator model calls only happen when you choose Run.', flush=True)
|
||||
child = subprocess.Popen([str(target / 'debug/buzz-accumulator'), '--key-file', str(keyfile), '--relay', args.relay, '--db', str(data / 'accumulator.db'), '--http-addr', '127.0.0.1:4640'], env=environment, cwd=data)
|
||||
try:
|
||||
sys.exit(child.wait())
|
||||
except KeyboardInterrupt:
|
||||
child.terminate()
|
||||
try:
|
||||
child.wait(timeout=10)
|
||||
except subprocess.TimeoutExpired:
|
||||
child.kill()
|
||||
child.wait()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except subprocess.CalledProcessError as error:
|
||||
sys.exit(f'Accumulator setup failed (exit {error.returncode}).')
|
||||
57
scripts/chief-model-runner.py
Executable file
57
scripts/chief-model-runner.py
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/python3
|
||||
"""Bounded text-only CLI adapter for the pinned Accumulator (macOS/Unix)."""
|
||||
import os
|
||||
import selectors
|
||||
import shutil
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def main():
|
||||
# The upstream runner starts this adapter as a process-group leader.
|
||||
# Keep the CLI in that group so the daemon's deadline contains both.
|
||||
if os.getpgrp() != os.getpid():
|
||||
sys.exit('The model adapter must be launched by the Accumulator.')
|
||||
args = sys.argv[1:]
|
||||
codex = args[:1] == ['exec']
|
||||
binary = shutil.which('codex' if codex else 'claude')
|
||||
if not binary:
|
||||
sys.exit('Install and sign in to the selected model CLI.')
|
||||
if codex:
|
||||
args = args[:-1] + ['--ignore-user-config', '--disable', 'shell_tool', '--disable', 'multi_agent', '--disable', 'apps', '--disable', 'plugins', '-c', 'web_search="disabled"', '-c', 'tools.view_image=false', '-c', 'project_doc_max_bytes=0', '-c', 'model_reasoning_effort="low"', '-']
|
||||
else:
|
||||
args += ['--strict-mcp-config', '--mcp-config', '{"mcpServers":{}}', '--no-session-persistence', '--disable-slash-commands']
|
||||
allowed = {'PATH', 'HOME', 'USER', 'TMPDIR', 'CODEX_HOME', 'HTTPS_PROXY', 'HTTP_PROXY', 'NO_PROXY', 'SSL_CERT_FILE', 'SSL_CERT_DIR', 'MAX_THINKING_TOKENS'}
|
||||
env = {key: value for key, value in os.environ.items() if key in allowed}
|
||||
child = subprocess.Popen([binary, *args], stdin=sys.stdin, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
|
||||
poller = selectors.DefaultSelector()
|
||||
poller.register(child.stdout, selectors.EVENT_READ, sys.stdout.buffer)
|
||||
poller.register(child.stderr, selectors.EVENT_READ, sys.stderr.buffer)
|
||||
deadline = time.monotonic() + 590
|
||||
size = 0
|
||||
while poller.get_map():
|
||||
if time.monotonic() > deadline:
|
||||
os.killpg(os.getpgrp(), signal.SIGKILL)
|
||||
for key, _ in poller.select(timeout=0.2):
|
||||
chunk = os.read(key.fileobj.fileno(), 8192)
|
||||
if not chunk:
|
||||
poller.unregister(key.fileobj)
|
||||
continue
|
||||
size += len(chunk)
|
||||
if size > 1_000_000:
|
||||
sys.stderr.write('Model output exceeded the local briefing limit.\n')
|
||||
sys.stderr.flush()
|
||||
os.killpg(os.getpgrp(), signal.SIGKILL)
|
||||
key.data.write(chunk)
|
||||
key.data.flush()
|
||||
while child.poll() is None:
|
||||
if time.monotonic() > deadline:
|
||||
os.killpg(os.getpgrp(), signal.SIGKILL)
|
||||
time.sleep(0.05)
|
||||
sys.exit(child.returncode)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
6
scripts/run-chief-accumulator.sh
Executable file
6
scripts/run-chief-accumulator.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Launch Riley's pinned service with the existing Buzz identity, kept out of logs.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
source ./bin/activate-hermit
|
||||
exec /usr/bin/python3 scripts/chief-accumulator.py "$@"
|
||||
38
scripts/test-chief-model-runner.py
Normal file
38
scripts/test-chief-model-runner.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""Regression checks at the actual CLI adapter boundary; no account or model call."""
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
ADAPTER = Path(__file__).with_name('chief-model-runner.py').resolve()
|
||||
|
||||
|
||||
class ModelAdapterTest(unittest.TestCase):
|
||||
def run_stub(self, source, environment=None):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
binary = Path(directory) / 'codex'
|
||||
binary.write_text('#!/usr/bin/python3\n' + source)
|
||||
binary.chmod(0o700)
|
||||
env = {**os.environ, 'PATH': directory + ':' + os.environ['PATH'], **(environment or {})}
|
||||
return subprocess.run([str(ADAPTER), 'exec', '--model', 'test', '-'], input='Synthetic test input', text=True, capture_output=True, env=env, start_new_session=True, timeout=15)
|
||||
|
||||
def test_clears_signing_environment_and_disables_tools(self):
|
||||
result = self.run_stub('import json,os,sys\nprint(json.dumps({"args":sys.argv[1:],"key_present":"BUZZ_PRIVATE_KEY" in os.environ,"input":sys.stdin.read()}))', {'BUZZ_PRIVATE_KEY': 'synthetic-test-secret'})
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
data = json.loads(result.stdout)
|
||||
self.assertFalse(data['key_present'])
|
||||
self.assertEqual(data['input'], 'Synthetic test input')
|
||||
for flag in ['--ignore-user-config', 'shell_tool', 'multi_agent', 'apps', 'plugins', 'web_search="disabled"']:
|
||||
self.assertIn(flag, data['args'])
|
||||
|
||||
def test_excess_output_fails_and_is_bounded(self):
|
||||
result = self.run_stub('import sys\nsys.stdout.write("x" * 2000000)\nsys.stdout.flush()')
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertLessEqual(len(result.stdout), 1_000_000)
|
||||
self.assertIn('exceeded', result.stderr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user