Skip to content

Feature: AI Assistant Module - #101

Draft
jhweir wants to merge 3 commits into
devfrom
feat/assistant-module
Draft

Feature: AI Assistant Module#101
jhweir wants to merge 3 commits into
devfrom
feat/assistant-module

Conversation

@jhweir

@jhweir jhweir commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

feat(assistant): AI-assistant feature module (port of #95)

Draft. Supersedes #95's WE-side changes by porting them onto the post-decomposition
structure (#100). UI is fully ported and verified below; live replies depend on the
AD4M-side runtime (coasys/ad4m#875), which this branch does not require to build or test.

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 writes
assistant Messages back (status: 'streaming''complete'), and live model subscriptions
render 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-assistant in module-system/ — which is the shape
the 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
defineModule declaration. Josh's authorship is preserved via a co-author trailer on the module
commit.

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.tsModuleDefinition.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 (Thread/Message do), so
    personal conversations work before any space is opened. ModuleStoreDeps gains rootDataset
    (personal-config storage) and an optional connection accessor (url/port/token) for modules
    that declare a backend and talk to its HTTP surface — null on hosts without one, degrading the
    same way presence does.
  • moduleRegistry.ts — predicate validation and model-class registration now run over the
    union of both model lists; new agentModels() accessor for the boot install.
  • moduleHostServices.ts / AdamStore.tsx — the host publishes the two new deps, and both
    root-perspective boot sites install registered agent models right after installRootSdna
    (same idempotent path).

The module (fc7ad77b) — packages/module-system/assistant/

  • Models (6): Thread/Message (space-scoped + agent-scoped) and Assistant/Personality/
    Skill/McpServer (agent-scoped config). Predicates migrated from feat(assistant): AD4M AI-assistant UI (WE front end) #95's flat we:// mints to
    the enforced module convention: novel properties mint under we://module/assistant/*; core
    vocabulary (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 fields
    works on assistant data for free. No data exists yet, so the migration is free.
  • Storefeat(assistant): AD4M AI-assistant UI (WE front end) #95's AssistantStoreProvider context component becomes createAssistantStore(deps)
    on the module contract. Threads/messages target the active dataset with root fallback; config
    CRUD always targets the root dataset; /v1/models discovery reads deps.connection and
    degrades to model ids referenced by existing threads/assistants when absent. Components reach
    the store through a module-scoped singleton, with AssistantContext kept as a test-injection
    override. New open/toggle/close state replaces the shell-view mechanism.
  • Surface — the shell-view template becomes an overlay slot gated on 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.
  • Components (4) — thread list, thread view (messages, tool calls, live stream, composer),
    config panel, message renderer. First module to ship its own Solid components
    (frameworks: ['solid']), exported as source like @we/editor so the host bundles a single
    Solid instance.
  • Tests — the 5 test files + mock store port to the module's own two-project vitest config
    (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 host
    component injection — the module ships its own) and adds assistant to the seed.
  • packages/app-shell/vitest.config.tsbundledModules.test.ts now imports Solid
    components 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

  • Live replies and real /v1/models responses need the executor from feat: AD4M AI-assistant runtime — /v1 tool-calling + server-side subsystem (verified e2e) ad4m#875. The client
    side already resolves @coasys/ad4m@0.13.0-test-9 via the workspace override, so nothing here
    blocks on it.
  • Renaming this branch to match the ad4m branch (feat/ai-assistant-runtime) would activate the
    CI cross-repo pairing (build.yaml links same-named ad4m branches); as-is, CI builds against
    ad4m dev, which this branch passes.
  • Surface placement is a faithful port (full overlay). Whether it should be a dock panel instead
    is a UX question deferred until the feature is used in anger.
  • AssistantMessage renders markdown via a minimal inline implementation from feat(assistant): AD4M AI-assistant UI (WE front end) #95; converging on
    we-markdown is a candidate cleanup.

Test plan

  • @we/module-assistant vitest: 30/30 (helpers + all four components against the mock store)
  • app-shell vitest: 9 files, 112 passing (includes assistant activation via bundledModules)
  • tsc --noEmit clean on @we/module-assistant and @we/app-shell
  • Full pnpm build from root succeeds
  • eslint clean on all touched packages
  • ai-context regeneration produces no diff
  • Browser verification (launcher, overlay, thread/message CRUD, config panels) — pending
  • Live replies against an executor built from feat: AD4M AI-assistant runtime — /v1 tool-calling + server-side subsystem (verified e2e) ad4m#875 — pending

jhweir and others added 3 commits August 3, 2026 15:00
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>
@netlify

netlify Bot commented Aug 3, 2026

Copy link
Copy Markdown

Deploy Preview for coasys-we ready!

Name Link
🔨 Latest commit 17e95a1
🔍 Latest deploy log https://app.netlify.com/projects/coasys-we/deploys/6a70a0273d3870000846db10
😎 Deploy Preview https://deploy-preview-101--coasys-we.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant