feat: composable context-intelligence behaviors — logging / analytics / full#27
Open
colombod wants to merge 11 commits into
Open
feat: composable context-intelligence behaviors — logging / analytics / full#27colombod wants to merge 11 commits into
colombod wants to merge 11 commits into
Conversation
… hook layers Create context-intelligence-nav behavior with navigation/exploration/tool-design capabilities (agents, modes, tools, skills, context) WITHOUT session telemetry hook. Rewrite context-intelligence.yaml to use nested composition: includes context-intelligence-nav behavior + adds hook-context-intelligence module only. This spike enables composing context-intelligence navigation into other apps without mandatory event capture. Full behavior still provides both query capabilities AND telemetry. Config resolver investigation confirmed hooks: and tools: use identical resolution (same parser, same _validate_module_list(), same SimpleSourceResolver), so nested composition pattern works cleanly. Generated with Amplifier Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Implement composable context-intelligence to support read-only analysis without event hooks. This allows apps to embed context navigation/querying/analysis features without requiring the event capture hook infrastructure. Key changes: - NEW: context_intelligence/standalone_resolver.py StandaloneConfigResolver reads server_url, api_key, workspace, base_path from AMPLIFIER_CONTEXT_INTELLIGENCE_* env vars and ~/.amplifier/settings.yaml. Provides fallback for tools when hook is not mounted. - Rename: behaviors/context-intelligence-nav.yaml -> context-intelligence-analytics.yaml Nav-only composition: agents + mode + tools + skills, no hook. Enables analytics-only deployment (querying existing session data). - MODIFIED: tool-graph-query, tool-blob-read Replaced "hook not configured" error with StandaloneConfigResolver fallback. Tools now work in analytics-only mode. - MODIFIED: hook config_resolver.py Added AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH env var to resolution chain (between coordinator.config and hardcoded default). Allows base_path override. - MODIFIED: behaviors/context-intelligence.yaml Now composes from context-intelligence-analytics (nav) + hook. Nested composition allows selective opt-in to event capture. - UPDATED: context-intelligence-awareness.md, session-navigator.md Documented two composition modes and BASE_PATH env var resolution. Session-navigator now resolves BASE_PATH from env at investigation start. Composition strategy (Option 1: nested YAML includes): - context-intelligence-analytics.yaml: read-only analysis (no hook) - context-intelligence.yaml: full feature set (analytics + hooks) Resolves via identical code paths for both tools and hooks. Generated with Amplifier Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
- Remove StandaloneConfigResolver (wrong abstraction per code review) - Pass config dict to tools instead of bypassing mount() convention - Add base_path as configurable env var (AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH) - Update graph-analyst to interpolate server_url, api_key, workspace from env vars - Replace all hardcoded ~/.amplifier/projects paths with $BASE_PATH in session-navigator This enables analytics-only behavior (context-intelligence-analytics.yaml) to work without the hook, using inline config fallback in tools instead of depending on coordinator capabilities registered at hook mount time. Fixes: - modules/tool-graph-query: GraphQueryTool.__init__ accepts config dict, execute() uses config fallback when hook capability is absent - modules/tool-blob-read: BlobReadTool.__init__ accepts config dict, same fallback - behaviors/context-intelligence.yaml: expose base_path via env var interpolation - agents/session-navigator.md: parameterize storage paths for multi-tenant usage Generated with Amplifier Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
…lobReadTool
Add TestAnalyticsOnlyMode class to both tool test files to cover the
fallback path introduced when the context_intelligence.config_resolver
capability is absent (no hook mounted).
- test_graph_query_tool.py: 3 new tests
- test_analytics_only_success: verifies config dict drives AsyncCIClient
construction (server_url, api_key) and workspace forwarded to cypher()
- test_analytics_only_workspace_defaults_to_default: no workspace key in
config falls back to 'default'
- test_analytics_only_no_server_url_returns_error: documents error message
is 'server URL not configured' (not 'hook not configured')
- test_blob_read_tool.py: 2 new tests
- test_analytics_only_success: verifies config dict drives AsyncCIClient
construction with correct server_url and api_key
- test_analytics_only_no_server_url_returns_error: documents error message
is 'server URL not configured' (not 'hook not configured')
Split configuration resolution into HookConfigResolver (full lifecycle context)
and ToolConfigResolver (analytics-only mode) with shared resolution chain.
**Core changes:**
- Extract shared _ENV_PREFIX constant and _env() helper to context_intelligence.config
- Rename ConfigResolver → HookConfigResolver with explicit semantics
- Add ToolConfigResolver for analytics-only execution path (4-level resolution chain)
- Update both tools to lazily instantiate ToolConfigResolver in execute() when hook unavailable
**Resolution chain (identical for both resolvers):**
1. mount() config dict / tool._config (highest priority)
2. coordinator.config
3. AMPLIFIER_CONTEXT_INTELLIGENCE_{SERVER_URL,API_KEY,WORKSPACE} env vars
4. ~/.amplifier/settings.yaml
5. defaults (workspace only: 'default', others: None)
**Key behavioral differences:**
- HookConfigResolver.workspace auto-derives from session.working_dir (hook lifecycle only)
- ToolConfigResolver.workspace falls back to env var / "default" (no session context)
- Both resolve server_url and api_key identically via 4-level chain
- Workspace caching and lazy property evaluation preserved in both
**Testing:**
- Rename all ConfigResolver → HookConfigResolver refs in test_config_resolver.py (70+ usages)
- Fix 4 tests that weren't clearing env vars before None assertions
- Add test_tool_resolver.py: 33 tests covering ToolConfigResolver chain, caching, and interface
- Coverage: analytics-only success paths, env var precedence, coordinator.config fallthrough
- All 172 tests passing, 0 failures
**Documentation:**
- Update README.md, all docs, diagrams (config-resolution.dot, logging-handler-flow.dot)
- Update agents/graph-analyst.md, skills/context-intelligence-session-navigation/SKILL.md
- Clarify dual-path library template for mount() config capture pattern
Generated with Amplifier
The capability key 'context_intelligence.config_resolver' is renamed to
'context_intelligence.hook_config_resolver' to explicitly document that
the tool is looking for the HOOK's resolver before falling back to
ToolConfigResolver.
This makes the intent self-documenting: reading
'get_capability("context_intelligence.hook_config_resolver")' in the
code now clearly signals the lookup behavior to maintainers.
Changes across 6 modules and tests:
- modules/hook-context-intelligence: register/unregister calls
- modules/tool-graph-query: get_capability call + test
- modules/tool-blob-read: get_capability call
- README.md: documentation example
Mechanical ruff formatting applied to test files after ConfigResolver → HookConfigResolver rename. No logic changes, formatting only. - modules/hook-context-intelligence/tests/test_config_resolver.py - modules/hook-context-intelligence/tests/test_mount_dispatcher.py - modules/tool-graph-query/tests/test_graph_query_tool.py Fixes CI Lint failure.
…e analytics Completes code review cleanup for the composable analytics behavior PR: - Rename `context_intelligence.config_resolver` -> `context_intelligence.hook_config_resolver` across all docstrings, comments, README, and test assertion messages (executable code was already renamed in the PR) - Add `# type: ignore[attr-defined]` suppression on `_env` private import in context_intelligence/tool_resolver.py to fix pyright error (mirrors existing suppression in config_resolver.py) - Fix type annotation in blob_read_tool.py (`self._resolver: Any` -> `Any | None`) to match graph-query tool - Add late-mount integration test proving tool upgrades from ToolConfigResolver fallback to hook resolver when hook mounts after first tool execute() Note: Two other review items (blob-read path-traversal guard and server_url scheme allowlist) are intentionally deferred for deeper analysis. Generated with Amplifier Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Resolve conflicts in hook-context-intelligence config_resolver. - config_resolver.py: keep the branch's HookConfigResolver rename and its DRY import of _env from context_intelligence.config; adopt main's new _DEFAULT_EXCLUDE_EVENTS = ["llm:stream_*delta"] default (commit a9ce2a8, align exclude_events with hooks-logging). Dropped main's local _ENV_PREFIX and local _env() since _env is now imported from the shared config module. - test_config_resolver.py: keep `import fnmatch` for the new exclude_events tests; unify all resolver constructor calls to HookConfigResolver. Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
…viors Add a dedicated hook-only `context-intelligence-logging` behavior and refactor the full `context-intelligence` behavior to compose it alongside the existing analytics behavior via `includes:`. Consumers can now pick granularity: logging-only (instrument the session), analytics-only (read/query, no hook), or full (both). The hook is registered exactly once. - behaviors/context-intelligence-logging.yaml: new hook-only behavior (hook-context-intelligence + full config), own bundle name. - behaviors/context-intelligence.yaml: drop inline hooks; includes analytics + logging. - context/context-intelligence-awareness.md: document three composition modes. - tests: point hook-shape assertions at the logging behavior; add full-behavior composition tests and logging-behavior structure tests. Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
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.
Summary
Splits context-intelligence into three composable behaviors so consumers pick exactly the capabilities they need — instrumentation, read/query, or both.
context-intelligence-loggingcontext-intelligence-analyticscontext-intelligence(full)includes:Why
Previously the hook was inlined in the full behavior, so a consumer wanting pure telemetry had to pull in the entire analytics surface, and there was no symmetric "logging-only" counterpart to the analytics-only behavior. Splitting the producer (hook) from the consumer (agents/tools) makes them independently composable.
Changes
behaviors/context-intelligence-logging.yaml— hook-only behavior (hook-context-intelligencemodule + full config), distinct bundle name.behaviors/context-intelligence.yaml— no longer inlines the hook; nowincludes:analytics + logging. Composition is equivalent to before, with the hook registered exactly once.behaviors/context-intelligence-analytics.yaml— unchanged.context/context-intelligence-awareness.md— documents the three composition modes.test_bundle.py/test_module_loading.py: hook-shape assertions now target the logging behavior; added full-behavior composition checks (includes both; no inline hook) and logging-behavior structure checks.Verification
test_skill_fetcher_mountfailures are unrelated to this change — reproduced on the branch with these changes stashed.)session:configcomposition record:Full behavior confirmed to register the hook exactly once despite composing both behaviors.
Also in this PR
mainmerge resolving conflicts inconfig_resolver.py(kept theHookConfigResolverrename + DRY_envimport; adopted main's_DEFAULT_EXCLUDE_EVENTS = ["llm:stream_*delta"]default) andtest_config_resolver.py.