Skip to content

feat(langgraph): hoist threads adapter + Client helper out of demos#488

Merged
blove merged 3 commits into
mainfrom
claude/hoist-threads-adapter
May 20, 2026
Merged

feat(langgraph): hoist threads adapter + Client helper out of demos#488
blove merged 3 commits into
mainfrom
claude/hoist-threads-adapter

Conversation

@blove
Copy link
Copy Markdown
Contributor

@blove blove commented May 20, 2026

Summary

  • createLangGraphClient(apiUrl) — wraps new Client({ apiUrl }) with the absolute-URL rewrite (/apiwindow.location.origin + /api) the SDK requires. Single source of truth. fetch-stream.transport.ts goes through it now instead of inlining the same workaround.
  • LangGraphThreadsAdapter — Angular service wrapping client.threads.search/create/delete/rename/update with the SDK→Thread mapping. Configurable via LANGGRAPH_THREADS_CONFIG.titleMetadataKey so the demo ('title') and c-threads ('thread_title') can both share one implementation.
  • refreshOnRunEnd(agent, fn) — collapses the lastStatus = ...; effect(...) snippet both consumers duplicate for "refresh threads when a run finishes" into one line.
  • Both consumers converted — drops the demo's local 138-line shell/threads.service.ts AND c-threads' 89-line app/threads.service.ts (added 2 hours earlier in feat(c-threads): real SDK-backed threads + inline title generation #481). c-threads is the second consumer of the hoisted adapter — proves the per-cap titleMetadataKey config works.

Constraints honored

Test plan

  • 7 new adapter unit tests pass (libs/langgraph/src/lib/threads/threads-adapter.spec.ts)
  • Full @ngaf/langgraph test suite green (166 tests)
  • nx build langgraph green
  • nx build examples-chat-angular green
  • nx build cockpit-chat-threads-angular green
  • CI green

Follow-ups (not this PR)

  • Converge the metadata-key drift: have c-threads' Python graph write metadata.title (matching the demo) instead of metadata.thread_title, then drop the per-consumer titleMetadataKey config and default to 'title'.

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
threadplane Ready Ready Preview, Comment May 20, 2026 4:02pm

Request Review

blove and others added 2 commits May 20, 2026 08:51
The same SDK-backed ThreadsService has been duplicated across consumers
(canonical demo, c-threads cap, future caps). Hoist it into @ngaf/langgraph
so one implementation serves them all.

What's exported:

- createLangGraphClient(apiUrl) — wraps `new Client({ apiUrl })` with
  the absolute-URL rewrite (`/api` → `window.location.origin + /api`)
  the SDK requires. Single source of truth — fetch-stream.transport
  now goes through it instead of inlining the same workaround.

- LangGraphThreadsAdapter — Angular service wrapping
  client.threads.search/create/delete/rename/update with the SDK→Thread
  mapping. Configurable via LANGGRAPH_THREADS_CONFIG which titleMetadataKey
  to read ('title' for the demo, 'thread_title' for c-threads — spec
  2026-05-19-llm-generated-labels-design). Pin/archive/projects/sort
  supported. Failures log to console.error (no more silent catches —
  that's been hiding prod issues; see PR #486).

- refreshOnRunEnd(agent, fn) — collapses the
  `lastStatus = ...; effect(...)` snippet both consumers duplicated for
  "refresh threads when a run finishes" into one line.

Converts examples/chat to consume the adapter directly via
inject(LangGraphThreadsAdapter), drops the local 138-line
shell/threads.service.ts. c-threads' adapter conversion lands in a
follow-up (waiting on #481 merge).

@ngaf/chat stays adapter-agnostic — no new LangChain dependency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #481 added a c-threads-local ThreadsService; this drops it in
favor of the shared LangGraphThreadsAdapter (exported from
@ngaf/langgraph in this same PR). Configures the adapter via
LANGGRAPH_THREADS_CONFIG with titleMetadataKey: 'thread_title' to
match the cap's Python graph.

Inline run-end refresh effect collapses to refreshOnRunEnd(agent, fn).

c-threads is now the second consumer of the hoisted adapter — proves
the per-cap titleMetadataKey config works (demo uses 'title',
c-threads uses 'thread_title') without duplicating the SDK glue.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@blove blove force-pushed the claude/hoist-threads-adapter branch from e6d77e0 to b1269ff Compare May 20, 2026 15:53
@blove blove merged commit 324e8e1 into main May 20, 2026
2 checks passed
blove added a commit that referenced this pull request May 20, 2026
PR #488 already replaced the silent catch with console.error; that
half of the original debug PR is done. This adds the complementary
console.debug calls on invoke + resolve so prod inspection can
distinguish "never called" from "called but resolved empty" from
"called and threw."

Targets the demo.threadplane.ai cold-load bug where the sidenav stays
empty with no visible signal. After this lands, redeploy + reload the
demo + check the console: presence/absence of '[...] invoked' tells
us whether the effect even fires.

Tighten the log volume if it becomes noisy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
blove added a commit that referenced this pull request May 20, 2026
…h() (#486)

* debug(langgraph): add console.debug to LangGraphThreadsAdapter.refresh()

PR #488 already replaced the silent catch with console.error; that
half of the original debug PR is done. This adds the complementary
console.debug calls on invoke + resolve so prod inspection can
distinguish "never called" from "called but resolved empty" from
"called and threw."

Targets the demo.threadplane.ai cold-load bug where the sidenav stays
empty with no visible signal. After this lands, redeploy + reload the
demo + check the console: presence/absence of '[...] invoked' tells
us whether the effect even fires.

Tighten the log volume if it becomes noisy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(docs): regenerate api docs

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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