Skip to content

Commit b1569f1

Browse files
committed
Merge branch 'develop' into 'fb-LEAP-1292'
Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/13567909568
2 parents 36620cf + 17f8ca2 commit b1569f1

File tree

88 files changed

+1300
-648
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+1300
-648
lines changed

.github/workflows/follow-merge-upstream-repo-sync-v2.yml

Lines changed: 34 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,12 @@ concurrency:
1717
group: ${{ github.workflow }}-${{ inputs.branch_name }}
1818
cancel-in-progress: true
1919

20-
env:
21-
NODE: "18"
22-
YARN: "1.22"
23-
2420
jobs:
2521
sync:
2622
name: Sync PR
2723
runs-on: ubuntu-latest
2824
outputs:
29-
label-studio-sdk: "${{ steps.upstream-prs.outputs.label-studio-sdk }}"
25+
label-studio-sdk: "${{ fromJSON(steps.upstream-prs.outputs.shas).label-studio-sdk }}"
3026
steps:
3127
- uses: hmarr/debug-action@v3.0.0
3228

@@ -69,109 +65,18 @@ jobs:
6965
path: ./.github/actions-hub
7066

7167
- name: Get Upstream PRs
68+
uses: ./.github/actions-hub/actions/follow-merge-upstream-prs
7269
id: upstream-prs
73-
uses: actions/github-script@v7
74-
env:
75-
BRANCH_NAME: ${{ inputs.branch_name }}
7670
with:
77-
github-token: ${{ secrets.GIT_PAT }}
78-
script: |
79-
const { repo, owner } = context.repo;
80-
const branch_name = process.env.BRANCH_NAME;
81-
const pyProjectPath = "pyproject.toml";
82-
const repos = ["label-studio-sdk"];
83-
const repos_infra = [];
84-
const base_branch_name = 'develop';
85-
86-
let shas = {};
87-
88-
// GET UPSTREAM PRS
89-
let upstream_pulls = [];
90-
for (const repo of repos.concat(repos_infra)) {
91-
const {data: pulls} = await github.rest.pulls.list({
92-
owner,
93-
repo,
94-
state: "all",
95-
head: `${owner}:${branch_name}`,
96-
});
97-
const first_open_pull = pulls.find(e => e.state === 'open');
98-
const pull = first_open_pull || pulls[0];
99-
if (pull) {
100-
core.info(`PRs found for ${repo} ${pull.html_url} ${pull.merged_at ? 'merged' : pull.state} ${pull.merged_at ? pull.merge_commit_sha : pull.head.sha}`)
101-
upstream_pulls.push(pull);
102-
if (pull.merged_at) {
103-
shas[repo] = pull.merge_commit_sha;
104-
} else if (pull.state === 'open') {
105-
shas[repo] = pull.head.sha;
106-
}
107-
} else {
108-
core.notice(`No open upstream PRs found for ${repo}`)
109-
}
110-
}
111-
112-
// GET BASE VERSIONS
113-
const {data: pyprojectBlob} = await github.rest.repos.getContent({
114-
owner: owner,
115-
repo: repo,
116-
ref: base_branch_name,
117-
path: pyProjectPath,
118-
});
119-
const base_pyproject = Buffer.from(pyprojectBlob.content, pyprojectBlob.encoding).toString("utf8");
120-
for (const repo of repos) {
121-
const match = base_pyproject.match(new RegExp(`${repo}\/archive.*(?<sha>[a-f0-9]{40})`));
122-
if (match && match.groups.sha) {
123-
core.info(`Base version for ${repo} ${pyprojectBlob.html_url} ${match.groups.sha}`);
124-
shas[repo] = shas[repo] || match.groups.sha;
125-
} else {
126-
core.setFailed(`Could not parse ${repo} version from ${pyprojectBlob.html_url}`);
127-
}
128-
}
129-
130-
for (const [key, value] of Object.entries(shas)) {
131-
core.setOutput(key, value);
132-
}
133-
134-
core.info(`Base branch name ${base_branch_name}`);
135-
core.setOutput('base_branch_name', base_branch_name);
136-
137-
if (upstream_pulls.length > 0) {
138-
core.info(`Title ${upstream_pulls[0].title}`);
139-
core.setOutput('title', upstream_pulls[0].title);
140-
}
141-
142-
const upstream_prs_urls = upstream_pulls.map(e => e.html_url).join(',');
143-
core.info(`Upstream PRs URLs ${upstream_prs_urls}`);
144-
core.setOutput('upstream_prs_urls', upstream_prs_urls);
145-
146-
let assignees = [];
147-
for (const pull of upstream_pulls) {
148-
if (pull.user) assignees.push(pull.user.login);
149-
if (pull.assignee) assignees.push(pull.assignee.login);
150-
assignees.concat(pull.assignees.map(e => e.name));
151-
}
152-
assignees = assignees.filter(x => x !== 'robot-ci-heartex');
153-
core.info(`Assignees ${assignees.join(',')}`);
154-
core.setOutput('assignees', assignees.join(','));
155-
156-
if (assignees.length > 0) {
157-
const author_username = assignees[0];
158-
core.info(`Author username ${author_username}`);
159-
core.setOutput('author_username', author_username);
160-
}
161-
162-
let status = "open"
163-
if (upstream_pulls.every(p => p.merged_at)) {
164-
status = 'merged';
165-
} else if (upstream_pulls.every(p => p.closed_at)) {
166-
status = 'closed';
167-
}
168-
core.info(`Status: ${status}`);
169-
core.setOutput("status", status);
71+
branch_name: "${{ inputs.branch_name }}"
72+
poetry_repositories: "label-studio-sdk"
73+
infra_repositories: ""
74+
github_token: "${{ secrets.GIT_PAT }}"
17075

17176
- name: Git Configure
17277
uses: ./.github/actions-hub/actions/git-configure
17378
with:
174-
username: ${{ steps.upstream-prs.outputs.author_username }}
79+
username: ${{ github.event.client_payload.actor || steps.upstream-prs.outputs.author_username }}
17580

17681
- name: Git Merge
17782
id: merge
@@ -197,12 +102,12 @@ jobs:
197102
- name: Commit submodule
198103
shell: bash
199104
env:
200-
SDK_SHA: "${{ steps.upstream-prs.outputs.label-studio-sdk }}"
105+
SDK_SHA: "${{ fromJSON(steps.upstream-prs.outputs.shas).label-studio-sdk }}"
201106
COMMIT_MESSAGE: "Sync Follow Merge dependencies"
202107
COMMIT_MESSAGE_WORKFLOW_LINK: "Workflow run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
203108
run: |
204109
set -xeuo pipefail
205-
110+
206111
if [[ -n "${SDK_SHA}" ]]; then
207112
poetry add "https://github.com/HumanSignal/label-studio-sdk/archive/${SDK_SHA}.zip" --lock
208113
fi
@@ -223,6 +128,7 @@ jobs:
223128
with:
224129
github_token: ${{ secrets.GIT_PAT }}
225130
branch_name: "${{ steps.get-branch.outputs.branch_name }}"
131+
base_branch_name: "${{ steps.upstream-prs.outputs.base_branch_name }}"
226132
title: "${{ steps.upstream-prs.outputs.title }}"
227133
upstream_prs_urls: "${{ steps.upstream-prs.outputs.upstream_prs_urls }}"
228134

@@ -235,6 +141,30 @@ jobs:
235141
pullrequest_number: "${{ steps.get-pr.outputs.number }}"
236142
assignees: "${{ steps.upstream-prs.outputs.assignees }}"
237143

144+
- name: Add PR state Labels
145+
if: steps.upstream-prs.outputs.status == 'stale'
146+
uses: ./.github/actions-hub/actions/github-add-pull-request-labels
147+
continue-on-error: true
148+
with:
149+
github_token: ${{ secrets.GIT_PAT }}
150+
pullrequest_number: "${{ steps.get-pr.outputs.number }}"
151+
labels: "FM Stale"
152+
153+
- name: Merge Stale PR (Dry run)
154+
if: steps.upstream-prs.outputs.status == 'stale'
155+
continue-on-error: true
156+
shell: bash
157+
env:
158+
GIT_PAT: ${{ secrets.GIT_PAT }}
159+
BRANCH_NAME: "origin/${{ steps.get-branch.outputs.branch_name }}"
160+
BASE_BRANCH_NAME: "origin/${{ steps.upstream-prs.outputs.base_branch_name }}"
161+
run: |
162+
if git diff --quiet "${BASE_BRANCH_NAME}..${BRANCH_NAME}"; then
163+
echo "No changes detected."
164+
else
165+
echo "Changes detected in PR."
166+
fi
167+
238168
- name: Convert to ready for review
239169
if: steps.upstream-prs.outputs.status == 'merged'
240170
id: ready-for-review-pr

Dockerfile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,17 @@ ENV PATH="$VENV_PATH/bin:$PATH"
8787
# Copy dependency files
8888
COPY pyproject.toml poetry.lock README.md ./
8989

90+
# Set a default build argument for including dev dependencies
91+
ARG INCLUDE_DEV=false
92+
9093
# Install dependencies without dev packages
9194
RUN --mount=type=cache,target=$POETRY_CACHE_DIR,sharing=locked \
92-
poetry check --lock && poetry install --no-root --without test --extras uwsgi
95+
poetry check --lock && \
96+
if [ "$INCLUDE_DEV" = "true" ]; then \
97+
poetry install --no-root --extras uwsgi --with test; \
98+
else \
99+
poetry install --no-root --without test --extras uwsgi; \
100+
fi
93101

94102
# Install LS
95103
COPY label_studio label_studio

docker-compose.override.example.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
version: "3.9"
22
services:
33
app:
4+
build:
5+
args:
6+
- INCLUDE_DEV=true
47
env_file:
58
- .env
9+
10+
nginx:
11+
build:
12+
args:
13+
- INCLUDE_DEV=true

docs/source/guide/ask_ai.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
---
2-
title: About Ask AI - Beta 🧪
3-
short: Ask AI
2+
title: About AI Features - Beta 🧪
3+
short: AI features
44
tier: enterprise
55
type: guide
66
order: 0
77
order_enterprise: 356
8-
meta_title: About Ask AI
9-
meta_description: Information about using the Ask AI tool in Label Studio
8+
meta_title: About AI features
9+
meta_description: Information about using the AI features in Label Studio
1010
section: "Manage Your Organization"
1111
date: 2025-01-28 16:40:16
1212
---
1313

14-
The Ask AI tool is an LLM that has been trained on our documentation, codebase, and several other Label Studio resources.
14+
AI features in Label Studio use an LLM that has been trained on our documentation, codebase, and several other Label Studio resources.
1515

16-
You can use Ask AI to create or refine your labeling configuration. Instead of manually building labeling interfaces or project instructions from scratch, you can prompt the AI with a description of what your labeling project needs, and the AI generates a suggested configuration.
16+
You can use AI to create or refine your labeling configuration. Instead of manually building labeling interfaces or project instructions from scratch, you can prompt the AI with a description of what your labeling project needs, and the AI generates a suggested configuration.
1717

1818

1919
## What models do you use?
@@ -36,13 +36,13 @@ The model is trained on public resources like our documentation, codebase, blog,
3636

3737
We are on a Tier 5 OpenAI account, and opt out of all requests for training data.
3838

39-
We track requests to Ask AI to use as quality control, but they are only used to test the outputs of the model. For example: If Company X asks "Make a project to label opossums," we may notice that Ask AI did not provide a satisfactory answer and we may create configurations with opossums in them and train the model on them. The model would not be trained on any of Company X's questions or data.
39+
We track requests to our AI to use as quality control, but they are only used to test the outputs of the model. For example: If Company X asks "Make a project to label opossums," we may notice that our AI did not provide a satisfactory answer and we may create configurations with opossums in them and train the model on them. The model would not be trained on any of Company X's questions or data.
4040

4141
All tracked data is covered by our industry-leading [security and privacy policies](https://humansignal.com/security/).
4242

43-
## Can I disable Ask AI?
43+
## How do I enable or disable AI features?
4444

45-
Yes, contact us to disable this feature.
45+
You can enable AI features from the **Organization > Billing & Usage** page. Only users in the Owners role have access to view and modify this page.
4646

4747
## HIPAA compliance
4848

docs/source/guide/prompts_keys.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ There are two approaches to adding a model provider API key.
1818
* OpenAI
1919
* Vertex AI
2020
* Gemini
21+
* Anthropic
2122

2223
* In the second scenario, you add a separate API key per model. Examples include:
2324

@@ -58,6 +59,14 @@ The JSON credentials are required. You can also optionally provide the project I
5859

5960
Once added, all supported models will appear in the base model drop-down when you [draft your prompt](prompts_draft).
6061

62+
## Anthropic API key
63+
64+
You can only have one Anthropic key per organization. This grants you access to set of whitelisted models. For a list of these models, see [Supported base models](prompts_overview#Supported-base-models).
65+
66+
For information on getting an Anthropic API key, see [Anthropic - Accessing the API](https://docs.anthropic.com/en/api/getting-started#accessing-the-api).
67+
68+
Once added, all supported models will appear in the base model drop-down when you [draft your prompt](prompts_draft).
69+
6170
## Azure OpenAI key
6271

6372
Each Azure OpenAI key is tied to a specific deployment, and each deployment comprises a single OpenAI model. So if you want to use multiple models through Azure, you will need to create a deployment for each model and then add each key to Label Studio.

docs/source/guide/prompts_overview.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ With Prompts, you can:
4848

4949
| Provider | Supported models |
5050
| --- | --- |
51-
| **OpenAI** | gpt-3.5-turbo-16k* <br>gpt-3.5-turbo* <br>gpt-4 <br>gpt-4-turbo <br>gpt-4o <br>gpt-4o-mini <br>o3-mini<br><br>**Note:** We recommend against using GPT 3.5 models, as these can sometimes be prone to rate limit errors and are not compatible with Image data. |
51+
| **OpenAI** | gpt-3.5-turbo-16k* <br>gpt-3.5-turbo* <br>gpt-4 <br>gpt-4-turbo <br>gpt-4o <br>gpt-4o-mini <br>o3-mini <br>o1<br><br>**Note:** We recommend against using GPT 3.5 models, as these can sometimes be prone to rate limit errors and are not compatible with Image data. |
5252
| **Gemini** | gemini-2.0-flash-exp <br>gemini-1.5-flash <br>gemini-1.5-flash-8b <br>gemini-1.5-pro |
5353
| **Vertex AI** | gemini-2.0-flash-exp <br>gemini-1.5-flash <br>gemini-1.5-pro |
54+
| **Anthropic** | claude-3-5-haiku <br>claude-3-5-sonnet |
5455
| **Azure OpenAI** | [Azure OpenAI chat-based models](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models) <br><br>**Note:** We recommend against using GPT 3.5 models, as these can sometimes be prone to rate limit errors and are not compatible with Image data. |
5556
| **Custom** | [Custom LLM](prompts_create#Add-OpenAI-Azure-OpenAI-or-a-custom-model) |
5657

0 commit comments

Comments
 (0)