mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-09-13 21:37:13 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ecb8c65bc0 | |||
| 137bb4fdb3 |
@@ -2,6 +2,11 @@ name: Build and Publish to PyPI
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
source_ref:
|
||||||
|
description: 'Existing release tag to publish (for example v4.10.11)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
|
|
||||||
@@ -11,13 +16,39 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write # Required for trusted publishing to PyPI
|
id-token: write # Required for trusted publishing to PyPI
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
ref: ${{ inputs.source_ref || github.sha }}
|
||||||
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Validate release source and version
|
||||||
|
env:
|
||||||
|
RELEASE_TAG: ${{ inputs.source_ref || github.event.release.tag_name }}
|
||||||
|
run: |
|
||||||
|
python3 - <<'PY'
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import tomllib
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
tag = os.environ['RELEASE_TAG']
|
||||||
|
if not re.fullmatch(r'v[0-9]+\.[0-9]+\.[0-9]+', tag):
|
||||||
|
raise SystemExit('source_ref must be an existing release tag: vX.Y.Z')
|
||||||
|
def revision(ref):
|
||||||
|
return subprocess.check_output(['git', 'rev-parse', '--verify', ref], text=True).strip()
|
||||||
|
if revision('HEAD') != revision(f'refs/tags/{tag}^{{}}'):
|
||||||
|
raise SystemExit('Checked-out commit does not match the release tag')
|
||||||
|
version = tomllib.loads(Path('pyproject.toml').read_text())['project']['version']
|
||||||
|
if version != tag[1:]:
|
||||||
|
raise SystemExit(f'Package version {version} does not match tag {tag}')
|
||||||
|
print(f'Validated {tag} at {revision("HEAD")} (package {version})')
|
||||||
|
PY
|
||||||
|
|
||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
@@ -26,9 +57,9 @@ jobs:
|
|||||||
- name: Build frontend
|
- name: Build frontend
|
||||||
run: |
|
run: |
|
||||||
cd web
|
cd web
|
||||||
npm install -g pnpm
|
# Match the archive/Docker npm path; npm ci rejects older tags' stale npm lockfiles.
|
||||||
pnpm install
|
npm install --include=optional
|
||||||
pnpm build
|
npm run build
|
||||||
mkdir -p ../src/langbot/web/dist
|
mkdir -p ../src/langbot/web/dist
|
||||||
cp -r dist ../src/langbot/web/
|
cp -r dist ../src/langbot/web/
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ CLI uses. Create one in your Space account (Profile → Personal Access Tokens),
|
|||||||
then send it as a Bearer token:
|
then send it as a Bearer token:
|
||||||
|
|
||||||
```
|
```
|
||||||
Authorization: Bearer lbpat_...uests without a valid PAT get `401 Unauthorized`.
|
Authorization: Bearer <your-pat>
|
||||||
|
```
|
||||||
|
|
||||||
|
Requests without a valid PAT get `401 Unauthorized`.
|
||||||
|
|
||||||
## Client configuration
|
## Client configuration
|
||||||
|
|
||||||
@@ -66,6 +69,36 @@ All tools are read-only.
|
|||||||
state (available, unprobed, unavailable), then Space recommendation. Each
|
state (available, unprobed, unavailable), then Space recommendation. Each
|
||||||
item includes `availability.up`, `last_probed_at`, latency, and HTTP status.
|
item includes `availability.up`, `last_probed_at`, latency, and HTTP status.
|
||||||
|
|
||||||
|
## Runner usage recommendations
|
||||||
|
|
||||||
|
Use `search_plugins` with `runner_usage: "agent"` for Agent, pipeline, and
|
||||||
|
setup-wizard recommendations, or `runner_usage: "event"` for event processors.
|
||||||
|
The component kind remains `Runner`. Only these two exact values are accepted;
|
||||||
|
omit the optional field to preserve unfiltered browsing.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"query":"", "runner_usage":"agent", "page":1, "page_size":100}
|
||||||
|
```
|
||||||
|
|
||||||
|
Plugin results include `latest_version` and `runner_usages: string[]`, the
|
||||||
|
explicit union of usages in that latest installable version. Only recommend a
|
||||||
|
plugin when this array explicitly contains the target usage. Missing, empty,
|
||||||
|
malformed, or unknown usages must never mean agent-compatible. Event-only
|
||||||
|
plugins must never enter Agent recommendations. Empty filtered results are
|
||||||
|
valid while legacy packages await corrected releases; never remove the filter
|
||||||
|
to fill a recommendation list.
|
||||||
|
|
||||||
|
REST callers use `runner_usage` on both
|
||||||
|
`POST /api/v1/marketplace/extensions/search` and the compatibility
|
||||||
|
`POST /api/v1/marketplace/plugins/search`; preserve it during fallback. Add
|
||||||
|
`"type_filter":"plugin", "component_filter":"Runner"` on the unified endpoint.
|
||||||
|
Usage is ANDed with other filters before pagination and `total`; MCP/Skill items
|
||||||
|
do not match. Invalid REST values return HTTP 400.
|
||||||
|
|
||||||
|
Open the same filter in the webpage:
|
||||||
|
`https://space.langbot.app/market?type=plugin&component=Runner&runner_usage=agent`
|
||||||
|
(or `runner_usage=event`). Switch All / Agent / Event in the Runner usage row.
|
||||||
|
|
||||||
## Implementation & maintenance (for Space developers)
|
## Implementation & maintenance (for Space developers)
|
||||||
|
|
||||||
- Server: `internal/controller/mcp/server.go` (official Go MCP SDK
|
- Server: `internal/controller/mcp/server.go` (official Go MCP SDK
|
||||||
|
|||||||
Reference in New Issue
Block a user