Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
15 changes: 15 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/debian
{
"name": "Development",
"image": "mcr.microsoft.com/devcontainers/typescript-node:latest",
"features": {
"ghcr.io/devcontainers/features/node:1": {}
},
"postCreateCommand": "pnpm install",
"customizations": {
"vscode": {
"extensions": ["esbenp.prettier-vscode"]
}
}
}
76 changes: 76 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: "\U0001F41B Bug Report"
description: 'Submit a bug report to help us improve LangSmith. To report a _security_ issue, please instead use the security option below.'
labels: ['01 Bug Report']
body:
- type: markdown
attributes:
value: >
Thank you for taking the time to file a bug report. Before creating a new
issue, please make sure to take a few moments to check the issue tracker
for existing issues about the bug.

- type: checkboxes
id: tracing-method
attributes:
label: Tracing Method
description: 'Select whether you are tracing using LangChain or some other method:'
options:
- label: 'SDK/Client'
- label: 'REST API'
- label: 'With LangChain'
- label: 'Other'

- type: checkboxes
id: runtime-language
attributes:
label: Language
description: ''
options:
- label: 'JavaScript/TypeScript'
- label: 'Other'

- type: checkboxes
id: platform-environment
attributes:
label: Host
description: 'Indicate whether you are connected to the hosted LangSmith platform or running locally.'
options:
- label: 'Hosted (https://api.smith.langchain.com)'
- label: 'Self-hosted'
- label: 'Other'

- type: textarea
id: system-info
attributes:
label: Other System Info
description: Please share any other system info with us. You can view this by running `langsmith env` in your terminal.
placeholder: LangSmith SDK version, client runtime information,
validations:
required: true

- type: textarea
id: reproduction
validations:
required: true
attributes:
label: Reproduction
description: |
Please provide a [code sample](https://stackoverflow.com/help/minimal-reproducible-example) that reproduces the problem you ran into. It can be a Colab link or just a code snippet.
If you have code snippets, error messages, stack traces please provide them here as well.
Important! Use code tags to correctly format your code. See https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks#syntax-highlighting
Avoid screenshots when possible, as they are hard to read and (more importantly) don't allow others to copy-and-paste your code.

placeholder: |
Steps to reproduce the behavior:

1.
2.
3.

- type: textarea
id: expected-behavior
validations:
required: true
attributes:
label: Expected behavior
description: 'A clear and concise description of what you would expect to happen.'
9 changes: 9 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
blank_issues_enabled: true
version: 2.1
contact_links:
- name: Support Portal
url: https://support.langchain.com
about: Contact technical support for enterprise support requests.
- name: Discord
url: https://discord.gg/6adMQxSpJS
about: General community discussions
19 changes: 19 additions & 0 deletions .github/ISSUE_TEMPLATE/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Documentation
description: Report an issue related to the LangSmith documentation.
title: "DOC: <Please write a comprehensive title after the 'DOC: ' prefix>"
labels: [03 - Documentation]

body:
- type: textarea
attributes:
label: 'Issue with current documentation:'
description: >
Please make sure to leave a reference to the document/code you're
referring to.

- type: textarea
attributes:
label: 'Idea or request for content:'
description: >
Please describe as clearly as possible what topics you think are missing
from the current documentation.
21 changes: 21 additions & 0 deletions .github/ISSUE_TEMPLATE/feature-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: 'Feature request'
description: Submit a proposal/request for a new LangSmith feature
labels: ['02 Feature Request']
body:
- type: textarea
id: feature-request
validations:
required: true
attributes:
label: Feature request
description: |
A clear and concise description of the feature proposal. Please provide links to any relevant GitHub repos, papers, or other resources if relevant.

- type: textarea
id: motivation
validations:
required: true
attributes:
label: Motivation
description: |
Please outline the motivation for the proposal. Is your feature request related to a problem? e.g., I'm always frustrated when [...]. If this is related to another GitHub issue, please link here too.
18 changes: 18 additions & 0 deletions .github/ISSUE_TEMPLATE/other.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Other Issue
description: Raise an issue that wouldn't be covered by the other templates.
title: "Issue: <Please write a comprehensive title after the 'Issue: ' prefix>"
labels: [04 - Other]

body:
- type: textarea
attributes:
label: "Issue you'd like to raise."
description: >
Please describe the issue you'd like to raise as clearly as possible.
Make sure to include any relevant links or references.

- type: textarea
attributes:
label: 'Suggestion:'
description: >
Please outline a suggestion to improve the issue here.
38 changes: 38 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
target-branch: 'main'
schedule:
interval: 'monthly'
ignore:
- dependency-name: 'p-queue'
groups:
minor-and-patch:
patterns:
- '*'
update-types:
- 'minor'
- 'patch'
major:
patterns:
- '*'
update-types:
- 'major'
- package-ecosystem: 'github-actions'
directory: '/'
target-branch: 'main'
schedule:
interval: 'monthly'
groups:
minor-and-patch:
patterns:
- '*'
update-types:
- 'minor'
- 'patch'
major:
patterns:
- '*'
update-types:
- 'major'
33 changes: 33 additions & 0 deletions .github/scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Mirror maintenance

Pulls new `langsmith-sdk/js` commits hourly into one rolling PR.
To run manually, dispatch **Mirror from langsmith-sdk** from `main`.
Manual fixes on the mirror branch survive later runs. Slack notifies Thibaut of updates and failures.

## Resolve conflicts

1. Fix conflicts directly on the mirror branch. Check the PR and run artifacts for unapplied patches.
2. Push the fixes and remove `needs-manual-merge`.
3. Dispatch from `main` to resume.

## Review and merge

1. Port files listed as manual; check new public modules for entrypoint shims and exports.
2. Wait for CI to pass, then **rebase-merge** the mirror PR.
3. Rebase-merge the production promotion PR too. Check the release changelog before publishing.

Enable **Allow rebase merging** in repository settings if needed.
Closing an unmerged mirror PR discards its fixes; the next run replays from `main`.

## Formatting policy

Prettier formats handwritten and generated code. `.prettierrc.json` retains the
80-column, double-quote override for `src/lib/`; the version comes from `pnpm-lock.yaml`.

1. Run `scripts/format` locally. `scripts/lint` checks formatting without changing files.
2. Mirroring formats changed files after clean patch application, before committing.
3. Conflicted patches keep their markers. Run `scripts/format` after resolving them.
4. Keep formatter configuration in staging; upstream tooling files remain manual ports.

STLC seals custom changes from `main` and runs `scripts/lint` after regeneration.
Formatting-only changes can still conflict with later upstream edits; review them normally.
21 changes: 21 additions & 0 deletions .github/scripts/format-mirror.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# Format changed mirror files with the destination config before committing.
set -euo pipefail
cd "$1"

# Preserve conflict markers for manual resolution.
if [ -n "$(git diff --name-only --diff-filter=U)" ]; then
echo "Resolve mirror conflicts before formatting." >&2
exit 1
fi

files=()
while IFS= read -r -d '' file; do
case "$file" in
src/lib/*) files+=("$file") ;;
esac
done < <(git diff --name-only --diff-filter=ACM -z HEAD)

if ((${#files[@]})); then
./node_modules/.bin/prettier --write --ignore-unknown -- "${files[@]}"
fi
75 changes: 75 additions & 0 deletions .github/scripts/mirror-from-langsmith-sdk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
# Rewrite one langsmith-sdk commit for this repo and apply it with git apply --3way.
# Usage: mirror-from-langsmith-sdk.sh <python|js> <sha> <this-checkout> [out-dir]
# Run from a langsmith-sdk checkout. Writes to out-dir: status (clean|conflict|noop) and
# one-path-per-line lists manual, dropped, conflicts.
set -euo pipefail
lang=$1 sha=$2 staging=$(cd "$3" && pwd) out=${4:-$(mktemp -d)}
mkdir -p "$out"; out=$(cd "$out" && pwd)


case $lang in
python)
root=python gen=python/langsmith/_openapi_client
mapped='python/langsmith/|python/tests/|python/bench/'
# header lines only: python/langsmith -> src/langsmith, python/tests -> tests, python/bench -> bench
paths='s#(^| |/)python/langsmith/#\1src/langsmith/#g; s#(^| |/)python/(tests|bench)/#\1\2/#g'
text='s/langsmith\._openapi_client/langsmith/g'
;;
js)
root=js gen=js/src/_openapi_client
mapped='js/src/'
paths='s#(^| |/)js/src/#\1src/lib/#g'
# generated client sits one level above src/lib; its index is client.ts there
text='s#"\.\./_openapi_client/index\.js"#"../../client.js"#g; s#"\./_openapi_client/index\.js"#"../client.js"#g; s#"\.\./_openapi_client/#"../../#g; s#"\./_openapi_client/#"../#g'
;;
*) echo "lang must be python or js" >&2; exit 2 ;;
esac

rewrite=() dropped=() manual=()
while IFS= read -r f; do
if [[ $f == $gen/* ]]; then dropped+=("$f")
elif [[ $f =~ ^($mapped) ]]; then rewrite+=("$f")
else manual+=("$f")
fi
done < <(git diff --name-only --no-renames "$sha^" "$sha" -- "$root")

lines() { if (($#)); then printf '%s\n' "$@"; fi; }

lines ${dropped[@]+"${dropped[@]}"} > "$out/dropped"
lines ${manual[@]+"${manual[@]}"} > "$out/manual"
: > "$out/conflicts"
if ((${#rewrite[@]} == 0)); then echo noop > "$out/status"; exit 0; fi

git diff --binary --full-index --no-renames "$sha^" "$sha" -- "${rewrite[@]}" \
| sed -E "/^(diff --git |--- |\+\+\+ |rename (from|to) |copy (from|to) )/ { $paths; }" \
| sed -E "$text" > "$out/$lang.patch"

# --3way needs the preimage blobs in the target repo, rewritten like the patch so the index hashes match
for f in "${rewrite[@]}"; do
old=$(git rev-parse -q --verify "$sha^:$f" 2>/dev/null) || continue
new=$(git cat-file blob "$old" | sed -E "$text" | git -C "$staging" hash-object -w --stdin)
[[ $old == "$new" ]] || sed -i.bak "s/^index $old\.\./index $new../" "$out/$lang.patch"
done
rm -f "$out/$lang.patch.bak"

# apply per file so one unmergeable file does not abort the rest
awk -v o="$out" '/^diff --git /{n++} {print > sprintf("%s/chunk-%03d", o, n)}' "$out/$lang.patch"
failed=()
for c in "$out"/chunk-*; do
before=$(git -C "$staging" diff --name-only --diff-filter=U | wc -l)
if ! git -C "$staging" apply --3way "$c" 2>>"$out/apply.log"; then
after=$(git -C "$staging" diff --name-only --diff-filter=U | wc -l)
((after > before)) || failed+=("$(sed -nE 's#^diff --git a/(.*) b/.*#\1#p;q' "$c")")
fi
done
conflicts=()
while IFS= read -r f; do [[ -n $f ]] && conflicts+=("$f"); done < <(git -C "$staging" diff --name-only --diff-filter=U)

lines ${conflicts[@]+"${conflicts[@]}"} > "$out/conflicts"
for f in ${failed[@]+"${failed[@]}"}; do echo "$f (not applied, patch in the run artifact)"; done >> "$out/conflicts"

if ((${#conflicts[@]} + ${#failed[@]})); then echo conflict > "$out/status"
elif git -C "$staging" diff --quiet HEAD; then echo noop > "$out/status"
else echo clean > "$out/status"
fi
53 changes: 53 additions & 0 deletions .github/scripts/test-format-mirror.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
# Exercise the mirror formatter with the installed, locked formatter.
set -euo pipefail
repo=$(cd "$(dirname "$0")/../.." && pwd)
fixture=$(mktemp -d)
trap 'rm -rf "$fixture"' EXIT
cd "$fixture"
git init -q
git config user.name "Mirror formatter test"
git config user.email "mirror-test@example.invalid"
git config core.hooksPath /dev/null
ln -s "$repo/node_modules" "$fixture/node_modules"
cp "$repo/.prettierrc.json" "$repo/.prettierignore" "$fixture/"
mkdir -p src/lib
file="src/lib/format fixture.ts"
unrelated=unrelated.ts
bad='const value={answer:42}'
good='const value = { answer: 42 };'
printf '%s\n' "$good" > "$file"
printf '%s\n' "$good" > "$unrelated"
git add -- "$file" "$unrelated"
git commit -qm baseline

# Changed tracked files with spaces are formatted; unrelated and untracked files are not.
printf '%s\n' "$bad" > "$file"
printf '%s\n' "$bad" > "$unrelated"
printf '%s\n' "$bad" > untracked.py
git add -- "$file"
"$repo/.github/scripts/format-mirror.sh" "$fixture"
test "$(cat "$file")" = "$good"
test "$(cat "$unrelated")" = "$bad"
test "$(cat untracked.py)" = "$bad"

# Deleted files and an empty formatting selection must not invoke a formatter on the whole repo.
git add -- "$file"
git rm -q -- "$file"
"$repo/.github/scripts/format-mirror.sh" "$fixture"
test ! -f "$file"
test "$(cat "$unrelated")" = "$bad"

# Unmerged entries must fail without rewriting conflict markers.
mkdir -p "$(dirname "$file")"
printf '%s\n' '<<<<<<< HEAD' 'left' '=======' 'right' '>>>>>>> upstream' > "$file"
blob=$(printf '%s\n' "$good" | git hash-object -w --stdin)
printf '100644 %s 1\t%s\n100644 %s 2\t%s\n100644 %s 3\t%s\n' \
"$blob" "$file" "$blob" "$file" "$blob" "$file" | git update-index --index-info
cp "$file" before-conflict
if "$repo/.github/scripts/format-mirror.sh" "$fixture"; then
echo "Expected formatting to reject unresolved conflicts" >&2
exit 1
fi
cmp "$file" before-conflict
echo "Mirror formatting regression checks passed."
Loading
Loading