Submodule workflow docs + eyrie/hawk-core-contracts type alias merge#107
Merged
Conversation
Single gateway package owns all eyrie imports via a hawk-owned Provider interface. Config, routing, and engine wiring delegate through it, giving a swappable provider seam (verified by a stub test), centralized type translation, and one boundary that the audit rules can guard. The submodule pointer moves to the neutral-host-defaults eyrie commit that makes the credential-store default host-neutral.
Stateless model-lookup helpers (DefaultModel, Find, RecommendedModel, ...) previously built a fresh eyrie engine on every call. eyrie's Engine reloads its catalog and provider config from disk on each method call, so a single long-lived gateway returns identical freshness — construct it once. Keeps the defaultGateway(ctx) signature unchanged; ctx still flows through to every data call via the helpers.
Provider is now a composition of 7 role interfaces (Generator, NativeCompactor, ModelCatalog, CredentialManager, SelectionManager, GatewayInspector, CatalogMaintenance). Gateway embeds the roles directly so every existing caller (session_factory, translateProvider, config, routing) keeps working via the composite Provider. Drops 4 unused methods (Resolve, bare Preflight, ApplyGatewayEnvironment, MigrateProviderSecretsContext) that grep confirmed had no callers. provider_stub_test.go now builds Gateway with only the Generator role, proving stubs can depend on a narrow facet.
23 test files now import gateway instead of eyrie directly: - 22 fixture-only files use gateway.SetDefaultStore/MapStore/etc - session_factory_test.go uses gateway.Selection Gateway re-exports the credential test fixtures (SetDefaultStore, DefaultStore, MapStore, AccountForEnv, HasSecret) so tests inject fixtures through the single boundary. 11 genuine keepers stay exempt (they test eyrie itself: engine construction, event translation, Provider stub, catalog/config/registry internals). audit_test.go is a string-literal false positive.
go.mod eyrie pseudo-version now points at cb1efad (the Phase-0 commit that makes the credential-store service name and config-dir default host-neutral). go.sum refreshed. Verified build + test pass both with go.work (local replace) and GOWORK=off (CI/upstream path using the version string).
…icit
- translateProvider now holds only Generator + NativeCompactor (the two
roles it uses) instead of the full Provider.
- Extract the SetServiceName('hawk') side-effect out of New into a
documented, sync.Once-guarded declareHawkIdentity so it is explicit
and runs exactly once.
- Repin eyrie to 637ce7a (adds the legacy provider.json migration).
eyrie changes merged via PR #77 (not the closed neutral-host-defaults PR): host-neutral defaults, provider.json + categories.json legacy migration, poolside adapter. Repin to actual main tip.
SelfHealer.runCommand ran model-generated shell via a raw exec.CommandContext(ctx, sh, -c, command) that bypassed every guard the Bash tool enforces (IsDestructiveCommand, IsSuspicious, CommandReferencesSensitivePath, sandbox.WrapCommand). A jailbroken model could read ~/.hawk/provider.json or fork-bomb from a fix attempt. Now rejects commands that reference sensitive paths or are flagged destructive, returning a clear error before exec. Added tests for both rejection paths.
Background bash had three issues:
1. ran on the request ctx, so the task was killed when the HTTP/Tool
request timed out. Now uses an independent context.
2. no Setpgid → Process.Kill() only killed the parent bash, leaving
grandchildren (e.g. ) orphaned. Now sets
SysProcAttr{Setpgid:true} and stop() kills the whole group via
kill(-pgid, SIGKILL).
3. nested goroutine (a goroutine that spawned another to watch
shellCtx.Done) was redundant. Flattened into a single outer
goroutine that races cmd.Wait against shellCancel via a channel.
Applied the same Setpgid fix to the foreground Bash tool path.
- declareHawkIdentity() now runs as the FIRST line of gateway.New, before eyrieengine.New, matching its documented invariant that no credential read happens under the host-neutral default service name. - Added gateway.BuildCustomGateways as the single shared conversion loop; config.eyrie_engine and engine.session_factory now delegate to it so a new CustomProviderConfig field only wires once. - Fixed stale Gateway doc comment (no longer claims to embed Provider).
…services The Session struct carried three deprecated fields (DeploymentRouting, ContainerExecutor, ContainerRequired) that were dual-written with the sub-service instances and could drift out of sync on ReattachTransport. Now read through to the sub-services via getter methods: - DeploymentRouting() -> ChatService.DeploymentRouting() - ContainerExecutor()/ContainerRequired() -> ToolService.* Setters updated to write to the sub-service (source of truth). Also fixed SetGLMThinkingEnabled to update the ChatService (it previously only touched the legacy field, which the chat path never read). Deleted the unused ListLiveEngineModels wrapper.
Removed 6 unused Settings fields: MinimalMode, PaginatorMarginTop, PaginatorMarginBottom, AutoDarkTheme, AutoLightTheme, CustomHeaders. All were inert in production (only referenced by their own tests). Deleted IsMinimalMode helper and the MinimalMode/CustomHeaders tests; replaced with a DeploymentRouting merge test. MergeSettings already skips nil pointer overrides, so no behavior change there.
…onnect Extracted streamSSE and writeJSONResponse helpers from the 251-line handleChat. The SSE loop now select-s on r.Context().Done() so a client disconnect releases the session and bails immediately, instead of pushing events to a dead connection. Verified sanitizer lock: Sanitize takes RLock only to snapshot 3 config fields into locals, then releases — clean snapshot pattern, no bug.
- icons: Glyph/ASCII/Nerd no longer panic on unknown names (return ), preventing a registry load order issue from crashing the TUI. - snapshot: tests reverted to original Track(message) signature. - multiagent: git/go helper commands now accept and use the worker's ctx so they abort on mission cancellation instead of running to completion with context.Background().
Hawk's conversation DTOs (EyrieMessage, EyrieResponse, ChatOptions, ...) and StreamResult are now type aliases of the canonical port contract, the same definitions eyrie/client/core already aliases. Hawk's product vocabulary is now defined exactly once. StreamResult's Close() and NewStreamResult constructor now resolve to the contract; the few call sites updated to llm.NewStreamResult. Co-Authored-By: Claude <noreply@anthropic.com>
Engine conversation DTOs are now the canonical contract types, so the gateway's field-mapping helpers collapse: toEngineMessages/toEngineTools/ toEngineToolChoice/fromEngineResponse/fromEngineRoute/fromEngineUsage are identity, and fromEngineEvent only translates the event-type vocabulary (engine 'content_delta'->hawk 'content'). toEngineRequest/ChatOptions mapping remains, since request shaping is still real work. Co-Authored-By: Claude <noreply@anthropic.com>
- Add mutex to Session for thread-safe model/provider access - Centralize HTTP/WebSocket tool result parsing - Add required argument validation for MCP tools - Expand tilde-user references in bash tool normalization - Add unrecognized engine event logging in gateway - Reorder imports for consistency
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updates AGENTS.md with single submodule workflow, syncs submodule pointers to merged feat/llm-port-contract commits in eyrie and hawk-core-contracts.