Feature: AI Assistant Module - #101
Draft
jhweir wants to merge 3 commits into
Draft
Conversation
Modules with per-user configuration need storage that outlives any one space. ModuleDefinition gains agentModels — model classes installed into the agent's root dataset at boot, alongside the existing space-scoped models installed on space switch (an entity may appear in both lists, e.g. a conversation type that works before any space is opened). ModuleStoreDeps gains two host-published accessors to match: - rootDataset — the agent's root dataset, for personal-config stores - connection — backend connection details (url/port/token) for modules that declare that backend and talk to its HTTP surface directly; null on hosts without one, degrading like presence moduleRegistry now validates predicates and registers model classes over the union of both lists, and exposes agentModels() for the boot install. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Port of the AD4M AI-assistant surface (#95) into the module system as @we/module-assistant. The UI never calls a model: the store writes user Messages into the dataset, the AD4M backend observes and writes assistant Messages (status streaming → complete), and live model subscriptions render the growing content — so most of the original's shell wiring deletes into the module definition: - Models mint predicates under we://module/assistant/* per the module convention, reusing core vocabulary (we://name, we://title, we://content, we://status, …) where semantics match, so generic UI keeps working on assistant data for free. - AssistantStoreProvider becomes createAssistantStore(deps): threads + messages target the active dataset (root fallback), personal config (Assistant/Personality/Skill/McpServer) always targets the root dataset via the new agentModels/rootDataset contract. /v1/models discovery reads deps.connection, degrading to referenced model ids. - The shell view becomes an overlay slot gated on the store's open signal, launched from the module rail; the surface carries its own close control in place of the shell-view chrome. - First module to ship its own Solid components (frameworks: ['solid']), exported as source like @we/editor so the host bundles one Solid. - Tests port to the module's own two-project vitest setup (node for helpers, jsdom + solid transform for components), with the mock store injected via AssistantContext. Co-authored-by: Josh Field <10372036+HexaField@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Registers the assistant module as a bundled factory (it ships its own components, so unlike globe it takes nothing from the host) and adds it to the seed's module list. bundledModules.test.ts now imports Solid components through the assistant definition, which the plain node test environment cannot load (solid-js resolves to its server build). The app-shell vitest config splits into node + jsdom projects — the same shape as the module's own config — scoped so only that test pays for the DOM setup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
✅ Deploy Preview for coasys-we ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
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.
feat(assistant): AI-assistant feature module (port of #95)
Summary
#95 introduced an AI-assistant surface whose replies are produced by the AD4M backend: the UI
writes user
Messages into a perspective, the executor observes, runs the assistant, and writesassistant
Messages back (status: 'streaming'→'complete'), and live model subscriptionsrender the growing content. The UI never calls a model.
That PR predates the package decomposition, so most of what it touched has since moved or been
replaced by the module contract. Rather than rebasing through the reorg, this branch re-lands the
same feature as a feature module —
@we/module-assistantinmodule-system/— which is the shapethe decomposition built for exactly this kind of contribution. The result: of the 43 files #95
touched, roughly 12 survive as module content; the rest (store provider wiring, component registry
edits, schema/shell registration, sidebar nav entry, shell-view plumbing) delete into a single
defineModuledeclaration. Josh's authorship is preserved via a co-author trailer on the modulecommit.
The port needed two genuine extensions to the module contract (first commit), both of which pass
the "every-module or one-module?" test — any module with per-user configuration or a backend HTTP
surface will need them.
Changes
Contract: agent-scoped models + host connection deps (
dc4c223a)packages/module-system/shared/src/module.ts—ModuleDefinition.agentModels: modelclasses installed into the agent's root dataset at boot, alongside the existing space-scoped
modelsinstalled on space switch. An entity may appear in both lists (Thread/Message do), sopersonal conversations work before any space is opened.
ModuleStoreDepsgainsrootDataset(personal-config storage) and an optional
connectionaccessor (url/port/token) for modulesthat declare a backend and talk to its HTTP surface — null on hosts without one, degrading the
same way
presencedoes.moduleRegistry.ts— predicate validation and model-class registration now run over theunion of both model lists; new
agentModels()accessor for the boot install.moduleHostServices.ts/AdamStore.tsx— the host publishes the two new deps, and bothroot-perspective boot sites install registered agent models right after
installRootSdna(same idempotent path).
The module (
fc7ad77b) —packages/module-system/assistant/Thread/Message(space-scoped + agent-scoped) andAssistant/Personality/Skill/McpServer(agent-scoped config). Predicates migrated from feat(assistant): AD4M AI-assistant UI (WE front end) #95's flatwe://mints tothe enforced module convention: novel properties mint under
we://module/assistant/*; corevocabulary (
we://name,we://title,we://content,we://role,we://status,we://url,we://description) is reused where semantics match, so generic UI that displays those fieldsworks on assistant data for free. No data exists yet, so the migration is free.
AssistantStoreProvidercontext component becomescreateAssistantStore(deps)on the module contract. Threads/messages target the active dataset with root fallback; config
CRUD always targets the root dataset;
/v1/modelsdiscovery readsdeps.connectionanddegrades to model ids referenced by existing threads/assistants when absent. Components reach
the store through a module-scoped singleton, with
AssistantContextkept as a test-injectionoverride. New
open/toggle/closestate replaces the shell-view mechanism.modules.assistant.open,launched from the module rail (sparkle icon); the surface carries its own close control in
place of the old shell-view chrome.
config panel, message renderer. First module to ship its own Solid components
(
frameworks: ['solid']), exported as source like@we/editorso the host bundles a singleSolid instance.
(node for helpers, jsdom + solid transform for components). 30 tests.
backends: ['ad4m']is the honest label: decorated model classes plus the executor connection.Activation (
17e95a1c)bundledModules.ts/we-seed.json— registers the bundled factory (unlike globe, no hostcomponent injection — the module ships its own) and adds
assistantto the seed.packages/app-shell/vitest.config.ts—bundledModules.test.tsnow imports Solidcomponents through the assistant definition, which the plain node environment can't load
(solid-js resolves to its server build). The config splits into node + jsdom projects, scoped so
only that test pays for the DOM setup.
Known follow-ups
/v1/modelsresponses need the executor from feat: AD4M AI-assistant runtime — /v1 tool-calling + server-side subsystem (verified e2e) ad4m#875. The clientside already resolves
@coasys/ad4m@0.13.0-test-9via the workspace override, so nothing hereblocks on it.
feat/ai-assistant-runtime) would activate theCI cross-repo pairing (build.yaml links same-named ad4m branches); as-is, CI builds against
ad4m dev, which this branch passes.
is a UX question deferred until the feature is used in anger.
AssistantMessagerenders markdown via a minimal inline implementation from feat(assistant): AD4M AI-assistant UI (WE front end) #95; converging onwe-markdownis a candidate cleanup.Test plan
@we/module-assistantvitest: 30/30 (helpers + all four components against the mock store)tsc --noEmitclean on@we/module-assistantand@we/app-shellpnpm buildfrom root succeeds