Skip to content

Comments

fix(pipes): sync copilot sdk thinking#36

Merged
Fu-Jie merged 1 commit intomainfrom
feature/copilot-sdk-fix
Jan 26, 2026
Merged

fix(pipes): sync copilot sdk thinking#36
Fu-Jie merged 1 commit intomainfrom
feature/copilot-sdk-fix

Conversation

@Fu-Jie
Copy link
Owner

@Fu-Jie Fu-Jie commented Jan 26, 2026

This pull request introduces several documentation and workflow improvements for the GitHub Copilot SDK plugin, focusing on enhanced test standards, plugin usability, and publishing reliability. The most important changes are grouped below.

Documentation Updates:

  • Updated both English (README.md) and Chinese (README_CN.md) documentation to version 0.2.3, highlighting new features such as per-user overrides, improved thinking output reliability, formatting enforcement, and custom tools support. [1] [2]
  • Expanded configuration options in the documentation, including new parameters for debug logging, log levels, workspace info, custom environment variables, reasoning effort, formatting enforcement, and tool support. Per-user override settings are now clearly documented. [1] [2]
  • Added troubleshooting guidance for thinking output visibility and multimodal support. [1] [2]

Testing and Workflow Enhancements:

  • Added a new section to .github/copilot-instructions.md specifying mandatory use of free/low-cost models (gpt-5-mini, gpt-4.1) for Copilot SDK test scripts, prohibiting expensive models unless explicitly requested.
  • Improved the release workflow (release.yml) by adding a step that automatically updates plugin icon URLs to use absolute GitHub URLs, ensuring icons are correctly referenced in plugin files.

Publishing Reliability:

  • Enhanced the plugin publishing script (openwebui_community_client.py) to avoid overwriting existing post images during updates, preventing blank image issues. The script now checks for existing remote media before uploading new images and ensures remote post info is up-to-date for version checks. [1] [2] [3]

- Fix thinking visibility by passing user overrides into streaming

- Harden UserValves handling for mapping/instance inputs

- Update bilingual README with per-user valves and troubleshooting
Copilot AI review requested due to automatic review settings January 26, 2026 20:26
@Fu-Jie Fu-Jie merged commit 30cde9e into main Jan 26, 2026
4 checks passed
@github-actions
Copy link
Contributor

✅ Plugin Version Check / 插件版本检查

版本更新检测通过!PR 包含版本变化和更新说明。

Version check passed! PR contains version changes and update description.


版本变化 / Version Changes

插件更新 / Plugin Updates


This comment was generated automatically. / 此评论由自动生成。

@Fu-Jie Fu-Jie deleted the feature/copilot-sdk-fix branch January 26, 2026 20:26
@gemini-code-assist
Copy link

Summary of Changes

Hello @Fu-Jie, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request delivers a comprehensive update to the GitHub Copilot SDK plugin, focusing on improved user experience through clearer documentation of new features and configuration options. It also strengthens development practices by introducing cost-conscious testing standards and enhances the plugin's operational stability with more reliable publishing mechanisms and a refactored, more maintainable core codebase.

Highlights

  • Documentation & Features: Updated English and Chinese documentation for the Copilot SDK plugin (v0.2.3), highlighting new features such as per-user overrides, reliable thinking output, formatting enforcement, and custom tool support.
  • Testing Standards: Implemented new testing guidelines for the Copilot SDK, mandating the use of cost-effective models ('gpt-5-mini', 'gpt-4.1') for test scripts to optimize resource usage.
  • Publishing Reliability: Improved the plugin publishing script to prevent accidental overwriting of existing images and ensure accurate version checks, enhancing the release workflow.
  • Core Logic Refinements: Major refactoring of the Copilot SDK integration, introducing robust system prompt extraction, dynamic session configuration, enhanced frontend debug logging, and a new example tool ('generate_random_number').
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/release.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request enhances the GitHub Copilot SDK plugin with several new features and improvements, updating both English and Chinese versions to v0.2.3. The main changes focus on per-user configuration overrides, improved thinking output reliability, formatting enforcement, custom tools support, and enhanced publishing reliability.

Changes:

  • Added UserValves class enabling per-user overrides for reasoning effort, CLI path, debug mode, thinking visibility, and model ID
  • Implemented custom tools support with example random number generator tool
  • Added formatting enforcement features to improve output readability
  • Enhanced publishing script to prevent blank image issues during updates
  • Updated workflow to automatically fix plugin icon URLs for releases
  • Added testing guidelines to enforce use of free/low-cost models for Copilot SDK tests

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 60 comments.

Show a summary per file
File Description
plugins/pipes/github-copilot-sdk/github_copilot_sdk.py English version: Added UserValves, custom tools, formatting enforcement, improved debug logging and event handling
plugins/pipes/github-copilot-sdk/github_copilot_sdk_cn.py Chinese version: Same features as English but contains duplicate method definitions and undefined variable issues
plugins/pipes/github-copilot-sdk/README.md Updated English documentation with new features, configuration options, and troubleshooting
plugins/pipes/github-copilot-sdk/README_CN.md Updated Chinese documentation with same information as English version
scripts/openwebui_community_client.py Enhanced to check for existing remote images before uploading to prevent overwrites
.github/workflows/release.yml Added step to update plugin icon URLs to use absolute GitHub URLs
.github/copilot-instructions.md Added testing standards requiring use of free models for Copilot SDK tests
Comments suppressed due to low confidence (12)

plugins/pipes/github-copilot-sdk/github_copilot_sdk.py:565

  • Variable m_name is not used.
                    m_name = (

plugins/pipes/github-copilot-sdk/github_copilot_sdk_cn.py:702

  • Variable m_name is not used.
                    m_name = (

plugins/pipes/github-copilot-sdk/github_copilot_sdk.py:151

  • Overly complex 'del' method.
    def __del__(self):

plugins/pipes/github-copilot-sdk/github_copilot_sdk_cn.py:155

  • Overly complex 'del' method.
    def __del__(self):

plugins/pipes/github-copilot-sdk/github_copilot_sdk_cn.py:13

  • Import of 'time' is not used.
import time

plugins/pipes/github-copilot-sdk/github_copilot_sdk_cn.py:21

  • Import of 'sys' is not used.
import sys

scripts/openwebui_community_client.py:24

  • Import of 'Any' is not used.
from typing import Optional, Dict, List, Any, Tuple

plugins/pipes/github-copilot-sdk/github_copilot_sdk.py:679

  • Except block directly handles BaseException.
            except:

plugins/pipes/github-copilot-sdk/github_copilot_sdk_cn.py:833

  • Except block directly handles BaseException.
            except:

plugins/pipes/github-copilot-sdk/github_copilot_sdk.py:679

  • 'except' clause does nothing but pass and there is no explanatory comment.
            except:

plugins/pipes/github-copilot-sdk/github_copilot_sdk_cn.py:833

  • 'except' clause does nothing but pass and there is no explanatory comment.
            except:

scripts/openwebui_community_client.py:70

  • 'except' clause does nothing but pass and there is no explanatory comment.
        except Exception:

Comment on lines +778 to +785
if (
"gpt-5.2-codex"
not in self._collect_model_ids(
body={},
request_model=self.valves.MODEL_ID,
real_model_id=self.valves.MODEL_ID,
)[0].lower()
):
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential IndexError. The code attempts to access [0] on the result of _collect_model_ids() without checking if the list is empty. If no model IDs are collected, this will raise an IndexError. Add a check to ensure the list is not empty before accessing the first element, or use a safer approach like next(iter(...), "").lower().

Suggested change
if (
"gpt-5.2-codex"
not in self._collect_model_ids(
body={},
request_model=self.valves.MODEL_ID,
real_model_id=self.valves.MODEL_ID,
)[0].lower()
):
model_ids = self._collect_model_ids(
body={},
request_model=self.valves.MODEL_ID,
real_model_id=self.valves.MODEL_ID,
)
first_model_id = (model_ids[0] if model_ids else "").lower()
if "gpt-5.2-codex" not in first_model_id:

Copilot uses AI. Check for mistakes.
Comment on lines +270 to +291
python3 -c "
import sys
import re

file_path = '$file'
icon_url = '$TARGET_ICON_URL'

try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()

# Replace icon_url: ... with new url
# Matches 'icon_url: ...' and replaces it
new_content = re.sub(r'^icon_url:.*$', f'icon_url: {icon_url}', content, flags=re.MULTILINE)

with open(file_path, 'w', encoding='utf-8') as f:
f.write(new_content)
print(f'Successfully updated icon_url in {file_path}')
except Exception as e:
print(f'Error updating {file_path}: {e}', file=sys.stderr)
sys.exit(1)
"
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shell variable injection vulnerability in Python inline script. The variables $file and $TARGET_ICON_URL are directly interpolated into the Python string without proper escaping, which could lead to command injection if filenames contain special characters like single quotes. Use a safer approach by passing these as environment variables or arguments to avoid potential security issues.

Copilot uses AI. Check for mistakes.
# 恢复失败,磁盘上可能不存在该会话
self._emit_debug_log(
f"会话 {chat_id} 不存在或已过期,将创建新会话。"
reasoning_effort = (effective_reasoning_effort,)
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect assignment creates a tuple instead of a string. Line 1058 assigns reasoning_effort = (effective_reasoning_effort,) which creates a single-element tuple, but this variable is expected to be a string. This will likely cause type errors later when the value is used. Remove the parentheses and comma to assign the string value directly: reasoning_effort = effective_reasoning_effort. Note: this line appears to be debug/leftover code that may not even be necessary since reasoning_effort is not used in this scope.

Suggested change
reasoning_effort = (effective_reasoning_effort,)
reasoning_effort = effective_reasoning_effort

Copilot uses AI. Check for mistakes.
Comment on lines 1039 to 1120
if chat_id:
try:
# 尝试直接使用 chat_id 作为 session_id 恢复会话
session = await client.resume_session(chat_id)
self._emit_debug_log(f"已通过 ChatID 恢复会话: {chat_id}")
await self._emit_debug_log(
f"已通过 ChatID 恢复会话: {chat_id}", __event_call__
)

# 显示工作空间信息(如果可用)
if self.valves.DEBUG and self.valves.SHOW_WORKSPACE_INFO:
if session.workspace_path:
await self._emit_debug_log(
f"会话工作空间: {session.workspace_path}",
__event_call__,
)

is_new_session = False
except Exception:
except Exception as e:
# 恢复失败,磁盘上可能不存在该会话
self._emit_debug_log(
f"会话 {chat_id} 不存在或已过期,将创建新会话。"
reasoning_effort = (effective_reasoning_effort,)
await self._emit_debug_log(
f"会话 {chat_id} 不存在或已过期 ({str(e)}),将创建新会话。",
__event_call__,
)
session = None

if session is None:
# 创建新会话
from copilot.types import SessionConfig, InfiniteSessionConfig

# 无限会话配置
infinite_session_config = None
if self.valves.INFINITE_SESSION:
infinite_session_config = InfiniteSessionConfig(
enabled=True,
background_compaction_threshold=self.valves.COMPACTION_THRESHOLD,
buffer_exhaustion_threshold=self.valves.BUFFER_THRESHOLD,
session_config = self._build_session_config(
chat_id,
real_model_id,
custom_tools,
system_prompt_content,
is_streaming,
)
if system_prompt_content:
await self._emit_debug_log(
f"配置系统消息(模式: append)",
__event_call__,
)

session_config = SessionConfig(
session_id=(
chat_id if chat_id else None
), # 使用 chat_id 作为 session_id
model=real_model_id,
streaming=body.get("stream", False),
infinite_sessions=infinite_session_config,
)
# 显示系统配置预览
if system_prompt_content or self.valves.ENFORCE_FORMATTING:
preview_parts = []
if system_prompt_content:
preview_parts.append(
f"自定义提示词: {system_prompt_content[:100]}..."
)
if self.valves.ENFORCE_FORMATTING:
preview_parts.append("格式化指导: 已启用")

if isinstance(session_config, dict):
system_config = session_config.get("system_message", {})
else:
system_config = getattr(session_config, "system_message", None)

if isinstance(system_config, dict):
full_content = system_config.get("content", "")
else:
full_content = ""

await self._emit_debug_log(
f"系统消息配置 - {', '.join(preview_parts)} (总长度: {len(full_content)} 字符)",
__event_call__,
)

session = await client.create_session(config=session_config)

# 获取新会话 ID
new_sid = getattr(session, "session_id", getattr(session, "id", None))
self._emit_debug_log(f"创建了新会话: {new_sid}")

# 构建 Prompt
if is_new_session:
# 新会话,发送完整历史
full_conversation = []
for msg in messages[:-1]:
role = msg.get("role", "user").upper()
content = msg.get("content", "")
if isinstance(content, list):
content = " ".join(
[
c.get("text", "")
for c in content
if c.get("type") == "text"
]
await self._emit_debug_log(f"创建了新会话: {new_sid}", __event_call__)

# 显示新会话的工作空间信息
if self.valves.DEBUG and self.valves.SHOW_WORKSPACE_INFO:
if session.workspace_path:
await self._emit_debug_log(
f"会话工作空间: {session.workspace_path}",
__event_call__,
)
full_conversation.append(f"{role}: {content}")
full_conversation.append(f"User: {last_text}")
prompt = "\n\n".join(full_conversation)
else:
# 恢复的会话,只发送最后一条消息
prompt = last_text

# 构建 Prompt(基于会话:仅发送最新用户输入)
prompt = self._apply_formatting_hint(last_text)

Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undefined variable usage. The variable is_new_session is used at line 1129 in the init_msg logic, but it's only defined within the if chat_id: block. If chat_id is None or empty, is_new_session will be undefined when accessed, causing a NameError. The variable should be initialized before the if chat_id: block to ensure it's always defined. This issue exists in the Chinese version but the English version handles this differently by not using is_new_session in the same way.

Copilot uses AI. Check for mistakes.
real_model_id,
custom_tools,
system_prompt_content,
is_streaming,
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing parameter in method call. The _build_session_config method is defined with a reasoning_effort parameter (line 421), but when it's called at line 955, this parameter is not passed. This means the reasoning effort setting won't be applied to new sessions. Add reasoning_effort=effective_reasoning_effort to the method call arguments to ensure the user's reasoning effort setting is properly applied.

Suggested change
is_streaming,
is_streaming,
reasoning_effort=effective_reasoning_effort,

Copilot uses AI. Check for mistakes.
json_obj, indent=2, ensure_ascii=False
)
is_json = True
except:
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
done.set()
try:
queue.put_nowait(SENTINEL)
except:
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
done.set()
try:
queue.put_nowait(SENTINEL)
except:
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
input_tokens = safe_get_data_attr(event, "input_tokens", 0)
output_tokens = safe_get_data_attr(event, "output_tokens", 0)
total_tokens = safe_get_data_attr(event, "total_tokens", 0)
pass
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary 'pass' statement.

Copilot uses AI. Check for mistakes.
input_tokens = safe_get_data_attr(event, "input_tokens", 0)
output_tokens = safe_get_data_attr(event, "output_tokens", 0)
total_tokens = safe_get_data_attr(event, "total_tokens", 0)
pass
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary 'pass' statement.

Copilot uses AI. Check for mistakes.
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly updates the GitHub Copilot SDK integration for OpenWebUI, bumping the version to 0.2.3. Key changes include the introduction of per-user overrides for settings like reasoning effort, CLI path, debug mode, thinking display, and model ID. It adds support for custom tools, with an example generate_random_number tool, and enhances output formatting by adding automatic hints to the system prompt for better readability. The update also refines debug logging to output to the browser console, adds a LOG_LEVEL setting, and includes SHOW_WORKSPACE_INFO. The internal Python code has been refactored to centralize configuration, improve system prompt extraction from various sources, and enhance streaming event handling for messages, reasoning, and detailed tool execution events. Additionally, a new testing standard document has been added, recommending gpt-5-mini and gpt-4.1 for Copilot SDK related tests to manage costs. Review comments highlighted the need to catch more specific exceptions instead of bare except: blocks for better error handling and debugging, and pointed out a redundant line assigning reasoning_effort within an except block.

Comment on lines +409 to +410
except:
pass

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Catching a bare except: is too broad and can hide unexpected errors, making debugging difficult. It's best practice to catch specific exceptions that you anticipate, or at least Exception if you intend to catch all standard errors.

Suggested change
except:
pass
except json.JSONDecodeError:
self._emit_debug_log_sync("Warning: CUSTOM_ENV_VARS is not valid JSON.", __event_call__)
except Exception as e:
self._emit_debug_log_sync(f"Error processing CUSTOM_ENV_VARS: {e}", __event_call__)

session,
send_payload,
init_message: str = "",
__event_call__=None,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line appears to be a typo. It assigns a tuple (effective_reasoning_effort,) to reasoning_effort, but reasoning_effort is not used in this except block. This line can be safely removed.

Comment on lines +358 to +359
except:
pass

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Catching a bare except: is too broad and can hide unexpected errors, making debugging difficult. It's best practice to catch specific exceptions that you anticipate, or at least Exception if you intend to catch all standard errors.

Suggested change
except:
pass
except json.JSONDecodeError:
self._emit_debug_log_sync("Warning: CUSTOM_ENV_VARS is not valid JSON.", __event_call__)
except Exception as e:
self._emit_debug_log_sync(f"Error processing CUSTOM_ENV_VARS: {e}", __event_call__)

# 恢复失败,磁盘上可能不存在该会话
self._emit_debug_log(
f"会话 {chat_id} 不存在或已过期,将创建新会话。"
reasoning_effort = (effective_reasoning_effort,)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line appears to be a typo. It assigns a tuple (effective_reasoning_effort,) to reasoning_effort, but reasoning_effort is not used in this except block. This line can be safely removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant