godot ai 更新

This commit is contained in:
2026-10-23 16:56:35 +08:00
parent 5c0adb3a96
commit e2491bc4e1
26 changed files with 1800 additions and 127 deletions
+61
View File
@@ -613,6 +613,12 @@ static func configure(id: String, url: String = "", launch_context: Dictionary =
if not client.automatic_config_edits:
return _manual_edit_result(client, "configure")
var path_error := _config_path_resolution_error(client)
if path_error.is_empty():
path_error = _config_write_error(client, "configure")
if path_error.is_empty():
path_error = _config_create_error(client)
if path_error.is_empty():
path_error = _credentials_error(client)
if not path_error.is_empty():
return {"status": "error", "message": path_error}
## Capture `url` once so a port flip in EditorSettings between write and
@@ -857,6 +863,8 @@ static func remove(id: String, url: String = "", launch_context: Dictionary = {}
if not client.automatic_config_edits:
return _manual_edit_result(client, "remove")
var path_error := _config_path_resolution_error(client)
if path_error.is_empty():
path_error = _config_write_error(client, "remove")
if not path_error.is_empty():
return {"status": "error", "message": path_error}
if url.is_empty():
@@ -897,6 +905,49 @@ static func _config_path_resolution_error(client: Client) -> String:
return str(client.resolved_config_path_details().get("error", ""))
## Why Configure must not create this client's file although status may still
## read the path: `create_error` in `McpClient`'s candidate rules. Kept apart
## from the function above, whose signature `script/local-self-update-smoke`
## patches by exact match, in release trees as well as this one.
static func _config_create_error(client: Client) -> String:
if client.config_type == "cli":
return ""
return str(client.resolved_config_path_details().get("create_error", ""))
## Why neither Configure nor Remove may touch this client's file: this editor's
## Flatpak sandbox does not share it with the host (`McpClient.config_write_error`,
## or the CLI strategy's own rule for a client that writes through its CLI, where
## Configure and Remove differ). Every strategy refuses on it too; checking here
## puts the refusal ahead of launcher discovery and the lock.
static func _config_write_error(client: Client, action: String) -> String:
if client.config_type == "cli":
if action == "configure":
return CliStrategy.configure_write_error(client)
return CliStrategy.remove_write_error(client)
return client.config_write_error()
## Why Configure must not write an attach entry although the client's file is
## writable: this editor's Flatpak sandbox keeps Godot AI's credentials where
## the bridge that entry launches does not look. A missing entry is better
## than one known to be broken. Remove is not held to it.
static func _credentials_error(client: Client) -> String:
if client.command_shape == Client.CommandShape.NONE:
return ""
if not McpPathTemplate.flatpak_hides_credentials():
return ""
var app_id := McpPathTemplate.flatpak_app_id()
return (
"Godot runs in a Flatpak sandbox that keeps Godot AI's credentials to "
+ "itself, so the bridge %s starts could not connect and nothing was "
+ "changed. Run `flatpak override --user "
+ "--filesystem=xdg-config/godot-ai:create %s`, restart Godot, and try "
+ "again. docs/steam-capability-directory.md covers the other ways to "
+ "share them."
) % [client.display_name, app_id if not app_id.is_empty() else "<Godot's Flatpak ID>"]
# --- Strategy dispatch + verify (testable seam) --------------------------
static func _manual_edit_result(client: Client, action: String) -> Dictionary:
@@ -1240,6 +1291,16 @@ static func manual_command(id: String) -> String:
)
if cmd.is_empty():
return cmd
## The path above is the one outside Flatpak. When this sandboxed editor
## cannot see where a Flatpak build keeps the same file, that may be the
## wrong one for this user, and this text is all a refused Configure (or a
## manual-only client) leaves them to go on.
var hidden_paths: Variant = path_resolution.get("hidden_paths", null)
if hidden_paths is PackedStringArray and not hidden_paths.is_empty():
cmd += (
"\n\nA Flatpak build keeps this file at %s instead. Godot's own Flatpak "
+ "sandbox cannot see it, so edit that one if it is the build you use."
) % " or ".join(hidden_paths)
## #507: when the allow-host opt-in names a non-loopback range, also
## surface the LAN URL so the user can copy-paste the right address into
## a remote agent. Informational only — configure/remove still WRITE the