feat(langsmith): add run update, get run, and feedback tools#5363
Conversation
…ership workflow edits via sockets, ui improvements
…ng improvements, posthog, secrets mutations
…ration, signup method feature flags, SSO improvements
…nts, secrets performance, polling refactors, drag resources in mothership
…y invalidation, HITL docs
…endar triggers, docs updates, integrations/models pages improvements
…ions, jira forms endpoints
…mat, logs performance improvements fix(csp): add missing analytics domains, remove unsafe-eval, fix workspace CSP gap (#4179) fix(landing): return 404 for invalid dynamic route slugs (#4182) improvement(seo): optimize sitemaps, robots.txt, and core web vitals across sim and docs (#4170) fix(gemini): support structured output with tools on Gemini 3 models (#4184) feat(brightdata): add Bright Data integration with 8 tools (#4183) fix(mothership): fix superagent credentials (#4185) fix(logs): close sidebar when selected log disappears from filtered list; cleanup (#4186)
v0.6.46: mothership streaming fixes, brightdata integration
…m integration, atlassian triggers
|
@cursor review |
Greptile SummaryThis PR extends the LangSmith block from a create-only integration to a full tracing lifecycle by adding
Confidence Score: 5/5Safe to merge — all three new tools have proper HTTP error guards and the block wiring is consistent. The new tools are well-structured, previously flagged issues (hardcoded success, ignored response body, missing response.ok guards, NaN score coercion, boolean score type) have all been addressed in earlier commits. The remaining observation is a minor empty-string inconsistency for optional feedback fields that does not cause data corruption or workflow failures. No files require special attention. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Block as LangSmith Block
participant Tool as Tool Config (params fn)
participant API as api.smith.langchain.com
Note over Block,API: Create Run (existing)
Block->>Tool: "operation=langsmith_create_run"
Tool->>API: "POST /runs {id, name, run_type, inputs, ...}"
API-->>Tool: 202 Accepted
Tool-->>Block: "{accepted, runId, message}"
Note over Block,API: Update Run (new)
Block->>Tool: "operation=langsmith_update_run, runId"
Tool->>API: "PATCH /runs/{runId} {outputs, status, end_time, ...}"
API-->>Tool: 200/204 + optional body
Tool-->>Block: "{accepted, runId, message}"
Note over Block,API: Get Run (new)
Block->>Tool: "operation=langsmith_get_run, runId"
Tool->>API: "GET /runs/{runId}"
API-->>Tool: "200 {id, name, run_type, status, inputs, outputs, ...}"
Tool-->>Block: "{id, runId, name, runType, status, inputs, outputs, ...}"
Note over Block,API: Create Feedback (new)
Block->>Tool: "operation=langsmith_create_feedback, runId, key, score, ..."
Tool->>API: "POST /feedback {id, run_id, key, score, value, comment, ...}"
API-->>Tool: "200 {id, key, run_id, score, ...}"
Tool-->>Block: "{id, key, runId, score, value, comment, createdAt}"
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Block as LangSmith Block
participant Tool as Tool Config (params fn)
participant API as api.smith.langchain.com
Note over Block,API: Create Run (existing)
Block->>Tool: "operation=langsmith_create_run"
Tool->>API: "POST /runs {id, name, run_type, inputs, ...}"
API-->>Tool: 202 Accepted
Tool-->>Block: "{accepted, runId, message}"
Note over Block,API: Update Run (new)
Block->>Tool: "operation=langsmith_update_run, runId"
Tool->>API: "PATCH /runs/{runId} {outputs, status, end_time, ...}"
API-->>Tool: 200/204 + optional body
Tool-->>Block: "{accepted, runId, message}"
Note over Block,API: Get Run (new)
Block->>Tool: "operation=langsmith_get_run, runId"
Tool->>API: "GET /runs/{runId}"
API-->>Tool: "200 {id, name, run_type, status, inputs, outputs, ...}"
Tool-->>Block: "{id, runId, name, runType, status, inputs, outputs, ...}"
Note over Block,API: Create Feedback (new)
Block->>Tool: "operation=langsmith_create_feedback, runId, key, score, ..."
Tool->>API: "POST /feedback {id, run_id, key, score, value, comment, ...}"
API-->>Tool: "200 {id, key, run_id, score, ...}"
Tool-->>Block: "{id, key, runId, score, value, comment, createdAt}"
Reviews (6): Last reviewed commit: "fix(langsmith): normalize empty-string p..." | Re-trigger Greptile |
- update_run, get_run, create_feedback now check response.ok before parsing/returning, matching the cloudwatch/zoom convention instead of silently returning success on a 4xx/404 - block outputs schema now exposes inputs/outputs for Get Run - update_run requires at least one field to patch, matching the batch-ingest guard for post/patch
|
@cursor review |
Greptile SummaryExtends the LangSmith block with three new operations —
Confidence Score: 3/5Mostly safe to merge, but Get Run is missing two of its most useful output fields from the block schema, limiting its practical usefulness in workflows. The block omits apps/sim/blocks/blocks/langsmith.ts (missing outputs) and apps/sim/tools/langsmith/update_run.ts (response body ignored) Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant W as Workflow Block
participant LS as LangSmith API
Note over W,LS: Create Run (existing)
W->>LS: "POST /runs {id, name, run_type, inputs…}"
LS-->>W: "200 {runId, message}"
Note over W,LS: Update Run (new)
W->>LS: "PATCH /runs/{runId} {outputs, status, end_time…}"
LS-->>W: 200 (body ignored → accepted: true)
Note over W,LS: Get Run (new)
W->>LS: "GET /runs/{runId}"
LS-->>W: "200 {id, name, status, inputs, outputs, …}"
Note right of W: inputs/outputs missing from block outputs schema
Note over W,LS: Create Feedback (new)
W->>LS: "POST /feedback {id(UUID), run_id, key, score…}"
LS-->>W: "200 {id, key, run_id, score, createdAt}"
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant W as Workflow Block
participant LS as LangSmith API
Note over W,LS: Create Run (existing)
W->>LS: "POST /runs {id, name, run_type, inputs…}"
LS-->>W: "200 {runId, message}"
Note over W,LS: Update Run (new)
W->>LS: "PATCH /runs/{runId} {outputs, status, end_time…}"
LS-->>W: 200 (body ignored → accepted: true)
Note over W,LS: Get Run (new)
W->>LS: "GET /runs/{runId}"
LS-->>W: "200 {id, name, status, inputs, outputs, …}"
Note right of W: inputs/outputs missing from block outputs schema
Note over W,LS: Create Feedback (new)
W->>LS: "POST /feedback {id(UUID), run_id, key, score…}"
LS-->>W: "200 {id, key, run_id, score, createdAt}"
|
…score type - get_run now also outputs runId (alias of id) so workflows can read the run identifier consistently across all operations on the block - update_run now parses and surfaces the response message instead of discarding the body entirely, matching create_run's pattern - narrow LangsmithCreateFeedbackParams.score to number — the tool param is declared as JSON-schema 'number' and the block's parseScore never produces a boolean, so the wider type was dead and misleading
|
@cursor review |
- block mapper now normalizes blank name/end_time/status/error inputs to undefined instead of forwarding empty strings, which would clear those fields on the LangSmith run - update_run tool now throws if the filtered PATCH body is empty, guarding direct/programmatic tool calls that bypass the block's own "at least one field" check
|
@cursor review |
… too Direct/agent tool calls bypass the block's own emptyToUndefined guard, so update_run now normalizes blank name/end_time/status/error itself before filtering, matching the block-level fix.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 51322c8. Configure here.
Summary
langsmith_update_run(PATCH /runs/{id}) to complete the standard create-then-patch tracing lifecyclelangsmith_get_run(GET /runs/{id}) to read a run's status/outputs back into a workflowlangsmith_create_feedback(POST /feedback) to attach scores, values, corrections, and comments to a runObject.fromEntries(...).filter(...)payload filtering to the sharedfilterUndefinedhelper across all langsmith toolsType of Change
Testing
Tested manually — verified endpoint existence and schemas against LangSmith's live OpenAPI spec (
api.smith.langchain.com/openapi.json) and live HTTP probing (401-vs-404 to confirm routes exist). Ranbun run lintandtsc --noEmitclean for all changed files.Checklist