* feat(github-copilot-sdk): add workspace skills support - Introduce ENABLE_WORKSPACE_SKILLS valve to enable/disable workspace custom tools discovery - Modify _build_session_config() to auto-load tools from .copilot-skills/ directory - Add workspace_skills_example.py template with 3 working example tools - Update README.md and README_CN.md with Workspace Skills guide and usage examples - Create v0.9.0.md and v0.9.0_CN.md release notes - Sync version to all docs files (index.md, index.zh.md, and main docs) - Bump version from 0.8.0 to 0.9.0 across all 7+ locations * docs: establish temp files handling policy (project-based, not /tmp) - Add TEMP_FILES_POLICY.md guideline for all skills and workflows - Update pr-submitter skill to use .temp/ directory instead of /tmp - Update release-prep skill documentation with temp file convention - Add .temp/ and .build/ entries to .gitignore - Create internal policy memo in /memories/repo/ This policy ensures: - All temporary files stay within project workspace (not system /tmp) - Alignment with OpenWebUI workspace isolation principles - Multi-user safety and cleanup traceability - Consistent handling across all skills and development workflows * fix(terminology): rename 'workspace skills' to 'workspace custom tools' for accuracy The term 'Skills' in Anthropic context refers to instruction-based frameworks (SKILL.md files with YAML frontmatter + markdown), not custom tool functions. Our implementation uses @define_tool decorator to define custom tools that the SDK auto-discovers from .copilot-skills/ directory. These are Tools, not Skills. Changes: - Rename ENABLE_WORKSPACE_SKILLS valve -> ENABLE_WORKSPACE_TOOLS - Update all documentation (README, README_CN, docs, release notes) - Fix section headings and descriptions throughout - Ensure consistent terminology across all files This is a terminology-only change; functionality remains identical. * feat(pipes): release v0.9.0 of GitHub Copilot SDK Pipe - Integrated OpenWebUI Skills Bridge and manage_skills tool - Reinforced status bar stability with session_finalized logic - Added persistent SDK config directory support * docs(pipes): add comprehensive guides and v0.9.0 notes for Copilot SDK - Added skill manager and best practices guides - Added publishing tool documentation - Included v0.9.0 release notes and deployment script - Updated usage guides
111 lines
3.8 KiB
Python
111 lines
3.8 KiB
Python
import requests
|
|
import json
|
|
import os
|
|
import re
|
|
from pathlib import Path
|
|
|
|
# ─── Configuration ───────────────────────────────────────────────────────────
|
|
SCRIPT_DIR = Path(__file__).parent
|
|
ENV_FILE = SCRIPT_DIR / ".env"
|
|
|
|
URL = (
|
|
"http://localhost:3003/api/v1/functions/id/github_copilot_official_sdk_pipe/update"
|
|
)
|
|
FILE_PATH = SCRIPT_DIR.parent / "plugins/pipes/github-copilot-sdk/github_copilot_sdk.py"
|
|
|
|
|
|
def _load_api_key() -> str:
|
|
"""Load API key from .env file in the same directory as this script.
|
|
|
|
The .env file should contain a line like:
|
|
api_key=sk-xxxxxxxxxxxx
|
|
"""
|
|
if not ENV_FILE.exists():
|
|
raise FileNotFoundError(
|
|
f".env file not found at {ENV_FILE}. "
|
|
"Please create it with: api_key=sk-xxxxxxxxxxxx"
|
|
)
|
|
|
|
for line in ENV_FILE.read_text(encoding="utf-8").splitlines():
|
|
line = line.strip()
|
|
if line.startswith("api_key="):
|
|
key = line.split("=", 1)[1].strip()
|
|
if key:
|
|
return key
|
|
|
|
raise ValueError("api_key not found in .env file.")
|
|
|
|
|
|
def update_pipe() -> None:
|
|
"""Push the latest local github_copilot_sdk.py content to OpenWebUI."""
|
|
# 1. Load API key
|
|
try:
|
|
api_key = _load_api_key()
|
|
except (FileNotFoundError, ValueError) as e:
|
|
print(f"[ERROR] {e}")
|
|
return
|
|
|
|
# 2. Read local source file
|
|
if not FILE_PATH.exists():
|
|
print(f"[ERROR] Source file not found: {FILE_PATH}")
|
|
return
|
|
|
|
content = FILE_PATH.read_text(encoding="utf-8")
|
|
|
|
# 3. Extract version from docstring
|
|
version_match = re.search(r"version:\s*([\d.]+)", content)
|
|
version = version_match.group(1) if version_match else "0.9.0"
|
|
|
|
# 4. Build payload
|
|
payload = {
|
|
"id": "github_copilot_official_sdk_pipe",
|
|
"name": "GitHub Copilot Official SDK Pipe",
|
|
"meta": {
|
|
"description": (
|
|
"Integrate GitHub Copilot SDK. Supports dynamic models, "
|
|
"multi-turn conversation, streaming, multimodal input, "
|
|
"infinite sessions, and frontend debug logging."
|
|
),
|
|
"manifest": {
|
|
"title": "GitHub Copilot Official SDK Pipe",
|
|
"author": "Fu-Jie",
|
|
"author_url": "https://github.com/Fu-Jie/openwebui-extensions",
|
|
"funding_url": "https://github.com/open-webui",
|
|
"openwebui_id": "ce96f7b4-12fc-4ac3-9a01-875713e69359",
|
|
"description": (
|
|
"Integrate GitHub Copilot SDK. Supports dynamic models, "
|
|
"multi-turn conversation, streaming, multimodal input, "
|
|
"infinite sessions, bidirectional OpenWebUI Skills bridge, "
|
|
"and manage_skills tool."
|
|
),
|
|
"version": version,
|
|
"requirements": "github-copilot-sdk==0.1.25",
|
|
},
|
|
"type": "pipe",
|
|
},
|
|
"content": content,
|
|
}
|
|
|
|
# 5. Build headers — use long-lived API key instead of short-lived JWT
|
|
headers = {
|
|
"Accept": "application/json",
|
|
"Content-Type": "application/json",
|
|
"Authorization": f"Bearer {api_key}",
|
|
}
|
|
|
|
# 6. Send update request
|
|
print(f"Updating pipe with version {version}...")
|
|
try:
|
|
response = requests.post(URL, headers=headers, data=json.dumps(payload))
|
|
if response.status_code == 200:
|
|
print("✅ Successfully updated GitHub Copilot Official SDK Pipe!")
|
|
else:
|
|
print(f"❌ Failed to update. Status: {response.status_code}")
|
|
print(f" Response: {response.text[:500]}")
|
|
except Exception as e:
|
|
print(f"❌ Request error: {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
update_pipe()
|