agents_main
Agents service entry point — scheduled background work and agents.
Runs AgentsService, a StargazerService
dedicated to recurring/background jobs so they never compete with the
latency-sensitive Inference workers. It owns the cluster-singleton
TaskSupervisor (leader-elected via a Redis lock,
so exactly one instance runs each cron job) and schedules tasks through a
BackgroundScheduler, including:
Knowledge-graph maintenance: auto KG extraction, agentic bulk incremental extraction, and channel summarization.
Limbic/NCM upkeep: maintenance, dedup, anchoring, sunset, and the journal stream.
Scheduled prompt ticks/cleanup and Gemini key probing.
It also boots optional background agents (DyadicEvaluator,
GameArtAgent, GameTurnAgent), the SWORD subsystem
(sword.factory.build_sword_system()), and the StarWiki service, and
persists embeddings asynchronously via EmbeddingBatchQueue.
Launched standalone (python agents_main.py) by
scripts/systemd/stargazer-agents.service.
- class agents_main.AgentsService(config, redis_client, instance_id)[source]
Bases:
StargazerServiceBackground-work microservice running scheduled jobs and agents.
Concrete
StargazerServicefor the agents tier. It isolates recurring/LLM-heavy work (KG extraction, limbic upkeep, journaling, key probing, channel summarization) from the latency-sensitive inference workers by owning a leader-electedTaskSupervisorand aBackgroundScheduler, plus optional background agents (dyadic evaluator, game art/turn agents), the SWORD subsystem and StarWiki.Instances are constructed by
main()(and by the migration tests undertests/core/migration/); the base class drives the lifecycle by callingon_start(),run()andon_stop()fromboot/shutdown.- __init__(config, redis_client, instance_id)[source]
Initialize the agents service and declare its component slots.
Wires up the base
StargazerServicewithservice_name="agents"and a required Redis client, then sets every heavyweight collaborator (message cache, KG manager, OpenRouter client, supervisor, embedding queue, event bus, background agents) toNoneso they can be lazily built inon_start(). TheBackgroundScheduleris the only collaborator constructed eagerly here.Interactions: calls
super().__init__onStargazerService(which may create aHealthServer) and constructs aBackgroundScheduler. No Redis or network I/O happens at construction time.Called by
main()when booting the standalone process, and directly by the migration tests intests/core/migration/that exercise the service in isolation.- Parameters:
config (
Config) – Loaded application configuration supplying Redis, OpenRouter/Gemini, model and feature-flag settings; stored asself.cfg.redis_client (
Any) – Async Redis client (decoded responses off) used for service registration, the supervisor lock and scheduled tasks.instance_id (
str) – Unique id for this process (e.g.agents-<hex>) used for service registration, the event-bus node id and the supervisor’s leader-election identity.
- get_adapter(platform_name)[source]
Return a proxy platform adapter that sends via the event bus.
Builds a
ProxyPlatformAdapterbound to this service’sRedisEventBusso background agents can emit outbound platform actions (messages, etc.) without owning a real platform connection; the inference/gateway tier consumes those events and performs the actual send.Interactions: constructs a fresh
ProxyPlatformAdapteroverself.event_buseach call (no caching). The bus must already be initialized inon_start(); calling this beforeon_startyields an adapter over aNonebus.Called by
on_start()to obtain the"discord"adapter for theGameArtAgentandGameTurnAgent, and by the agents migration tests; mirrors theget_adaptermethod on the inference and web services.- Parameters:
platform_name (
str) – Logical platform key (e.g."discord") the adapter will tag its outbound events with.- Returns:
Event-bus-backed adapter for
platform_name.- Return type:
- async on_start()[source]
Build collaborators and register all scheduled and supervised work.
Implements the abstract
on_startofStargazerService. Constructs theOpenRouterClient,MessageCache,KnowledgeGraphManager,EmbeddingBatchQueue,RedisEventBusandTaskSupervisor, then registers the supervisedlimbic_dedup_workerand a fleet of periodic jobs on theBackgroundScheduler(prompt tick/cleanup, auto and agentic-bulk KG extraction, channel summarization, optional log RAG ingest, Gemini key probe, limbic maintenance/anchoring/sunset, journal stream, anamnesis digest, and — when enabled — StarWiki). Finally it starts the supervisor and scheduler, kicks off SWORD bootstrap in the background, and starts the optional dyadic/game agents.Interactions: resolves SSL/connection kwargs from
Config; callsset_observability_redisfromobservability; awaitsembedding_queue.start(),event_bus.ensure_streams(),supervisor.start()andscheduler.start(); builds the SWORD system viasword.factory.build_sword_system()and, in a fire-and-forgetasyncio.create_task()(_bootstrap_sword), ensures SWORD indexes and loads Origin fragments fromsystem_prompt.j2before attaching the monitor to the KG manager. Conditionally constructs and startsStarwikiService,DyadicEvaluator,GameArtAgentandGameTurnAgent(the latter two over the"discord"adapter fromget_adapter()); agent startup failures are logged and swallowed so one failing agent cannot abort boot. Mutates the instance attributes declared in__init__().Called by
StargazerService.boot(Phase 3-7) after the Redis connection is verified; never invoked directly outside the migration tests.
- async run()[source]
Block forever so scheduled jobs and agents keep running.
Implements the abstract
runloop ofStargazerService. The agents service does no per-tick work in the foreground — the supervisor, scheduler and background agents started inon_start()drive everything — so this simply awaits a never-setasyncio.Eventuntil the task is cancelled at shutdown.Interactions: awaits
asyncio.Event().wait(); swallows theasyncio.CancelledErrorraised when the process is shutting down so cancellation unwinds cleanly.Called by
main()afterservice.boot()completes; cancellation is triggered by the SIGINT/SIGTERM handlers installed inmain(), which invokeservice.shutdown().- Return type:
- async on_stop()[source]
Tear down the scheduler, supervisor, agents and clients in order.
Implements the abstract
on_stopcleanup ofStargazerService, releasing everything stood up inon_start(). It stops the scheduler and supervisor first (halting new task launches and releasing the leader lock), then the game turn/art agents and dyadic evaluator, then the embedding queue, and finally closes the OpenRouter client.Interactions: awaits
scheduler.stop()andsupervisor.shutdown(); best-effort awaitsstop()onGameTurnAgent,GameArtAgent,DyadicEvaluatorandEmbeddingBatchQueue(each wrapped in try/except so one failure cannot block the rest), then awaitsopenrouter.close(). Each component is guarded by a truthiness check so partial-boot states shut down safely.Called by
StargazerService.shutdownafter service deregistration;shutdownitself is invoked by the signal handlers wired inmain().- Return type:
- async agents_main.main()[source]
Configure, boot and run the agents service as a standalone process.
Process entry point: sets up basic logging, loads
Config, mints anagents-<hex>instance id, builds an async Redis client and constructs anAgentsService. It installs SIGINT/SIGTERM handlers that schedule a gracefulservice.shutdown(), then boots and runs the service until cancellation, closing the Redis client in afinallyblock.Interactions: calls
Config.load()andcfg.build_async_redis_client(decode_responses=False); registers signal handlers on the running event loop that callservice.shutdown(); awaitsservice.boot()(which runson_start()) andservice.run(); guaranteesredis_client.aclose()on exit.Called by the
if __name__ == "__main__"guard viaasyncio.run()(launched byscripts/systemd/stargazer-agents.service) and is patched/awaited directly by the migration tests intests/core/migration/test_service_entrypoints.py.- Return type: