SearchResultProps does not declare a card_id field, so passing it caused
TS2769 type errors. search-result cards do not need loading→done dedup
(each google_search/web_search_deep call produces a complete result in one
push), so the card_id and associated local variables are unnecessary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each search result card now carries a unique card_id containing the tool call id
(e.g. google-search-<tc.id>), enabling the ToolCallStatus exact-match logic to
correctly bind cards to their originating tool call without index-based offset errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add parallel_tool_calls: false to searcher agentNode bindTools call so the
LLM is forced to execute search tools one at a time (google_search first,
then web_read in a separate turn); prompt-level "strict禁止" alone cannot
override model-side parallel tool calling behaviour
- Remove card_id field from google_search and web_search_deep ui.push props;
SearchResultProps does not declare card_id so the field caused TS2769
overload errors; these cards do not need deduplication (each search is a
distinct query), while the card_id variables were introduced by a previous
commit and are now unused
- Clean up unused googleCardId and deepCardId local variables
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add web_read -> web-read-progress mapping to standaloneUiItems filter in main.tsx
so web-read-progress cards are no longer mistakenly treated as standalone
- Add web-read-progress to CARD_TYPE_PRIORITY (550) to ensure stable sort order
and prevent search-result cards (500) from being reordered relative to web-read cards
- Add unique card_id (containing tc.id) to google_search and web_search_deep ui.push
calls so each search result card can be precisely identified
- Improve uiItem matching in ToolCallStatus to first try exact match via card_id
containing tc.id, falling back to index-based matching only when necessary;
this prevents index offset bugs when multiple same-type tools run concurrently
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When LLM sends multiple parallel tool_calls but one throws unexpectedly,
Promise.all loses all results causing 400 error from OpenAI.
Promise.allSettled ensures every tool_call_id gets a response.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Azure Container App auto-deploy workflow replaces our manual
deploy-langgraph.yml. CD is now managed via Azure Portal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8s timeout caused Jina Reader failures on slower sites like news.cn.
Increased to 30s with 2 retries and 1s backoff.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wraps all LoadExternalComponent usages with CardErrorBoundary so
card rendering errors show an inline error message instead of
crashing the entire app.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tool call status cards and execution log panel now expand by default
so users can see CoT process and results without clicking.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace soc-langgraph Web App with Azure Container App (soc-cae environment)
- New URL: soc-langgraph.victorioussand-69befc84.southeastasia.azurecontainerapps.io
- Update deploy-langgraph.yml: Web App restart -> az containerapp update --image
- Update deploy-langgraph-ui.yml: VITE_LANGGRAPH_URL to Container App URL
- Container App: min 1 replica, max 3, CPU 1.0, Memory 2Gi, port 8080
- Update CLAUDE.md architecture and deployment docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
server.ts production mode crashes on startup (exit code 1).
Revert to langgraphjs dev until startServer() compatibility is resolved.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
server.ts uses createRequire to resolve @langchain/langgraph-api at startup.
With pnpm, indirect dependencies are not hoisted to node_modules/@langchain/,
causing "Cannot find module" error and container exit code 1 on Azure.
Adding it as an explicit dependency ensures pnpm creates the direct symlink.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add web-read-progress Gen-UI card for real-time web reading feedback
- Searcher tool-executor pushes loading→complete cards during web_read
- ToolCallStatus supports expanding during loading state
- Switch from langgraphjs dev to production mode (server.ts)
- Add Hono middleware to strip sensitive request headers
- Bundle splitting via Vite manualChunks (1.85MB → 8 chunks)
- SPA fallback via staticwebapp.config.json
- Agent model configs updated (sonnet 1M → standard sonnet)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously web_search_deep tool calls were missing from the UI_NAME_MAP,
causing their search-result cards to render as standalone cards instead of
being embedded within the ToolCallStatus component row.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When tool rounds hit MAX_ITERATIONS, the router was jumping directly to
END without giving the LLM a chance to produce a final text reply.
Added a `force-summary` node that invokes the LLM without tools,
ensuring a coherent Chinese summary is always generated after all
search results are collected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The LangGraph API server injects all x-* request headers into
thread.config.configurable, which gets persisted and exposed via
POST /threads/search. This leaked Azure-injected headers (x-forwarded-for,
x-client-ip, x-arr-ssl, etc.) to any user.
Adds a Hono middleware (http.app) that strips sensitive infrastructure
headers at the HTTP layer before they reach the LangGraph API routes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace single pendingSubmitRef with pendingQueueRef array supporting multiple queued messages
- Add SubmitPayload interface to snapshot text/file/tools/modelMode at submission time
- Rewrite handleSubmit/doSubmit to use payload snapshots instead of closures over mutable state
- Rewrite handleConcurrentQueue with polling loop that drains the queue sequentially
- Rewrite handleConcurrentInterrupt and handleConcurrentCancel for queue awareness
- StreamStatusBar queued state now shows count (N 条消息已排队) and inline cancel button
- Add key={concurrentStatus} to StreamStatusBar div for fade-in animation on status change
- Config panel summary button shows numeric badge instead of dot when tools are active
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- filterTools now actually filters by modelMode (flash excludes search tools)
- Hard limit of 3 tool calls per turn in preValidateToolCall
- Temperature default changed from 0.5 to 0.2 to match MODEL_PRESETS.auto
- ticket_list blocked when message contains specific ticket ID (TK-xxxx)
- google_search/web_search_deep blocked for internal knowledge queries
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace flat tool toggles + model selector bar with a default-collapsed
summary chip (e.g. "Auto · 已开启 3 个工具 ▾") that expands upward into
a compact panel. Panel auto-closes on outside mousedown click. Options
changes keep the panel open.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Add showConcurrentDialog modal when submitting while AI is loading
- Offer interrupt (stop + submit) or queue (poll until done) options
- Remove disabled={thread.isLoading} from textarea and FileUploadButton
- Fix TS2352: cast BaseMessage to unknown first before Record
- Fix TS6133: rename unused toolName param to _toolName
- Fix TS2769: chart_type typed as union literal, not string
- Fix TS2322: separate cmdMap lookup from const declaration in soc-client
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Add CornerDownRight, AlertCircle icons for fallback/partial states
- New isPartial/isFallback props on ToolCallRow with hint banners
- Read execution_log from thread.values in main.tsx, pass to ToolCallStatus
- Match by tc.name === entry.tool to determine partial/fallback per row
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
GOOGLE_API_KEY is not used at startup (no code calls config.google.apiKey).
DATABASE_URL is only needed for production checkpointer. Both are now
warned-but-not-fatal in dev (NODE_ENV != production) to allow local
development without these credentials.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- coder/tool-executor: push sandbox-result card with friendly message on
failure instead of raw error, guide user to local execution or retry
- enterprise/tool-executor: skip ticket-summary card when ticket_list
returns empty, only return hint in tool message to avoid blank UI
- searcher/tool-executor: auto-supplement web_search_deep with
google_search when results < 3, matching existing google_search behavior
- ticket_detail UUID: already correctly uses find() match (no change needed)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Fix ToolCallStatus label duplication: label span was shown twice when
failed/done; consolidate into a single span with correct copy
- Add animate-in fade-in duration-300 wrapper to standalone Gen-UI cards
and streaming orphan cards in main.tsx (already present in ToolCallStatus
expanded view)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>