# Werkzeuge während einer Sitzung ändern

Eine Anwendung kann die tools ersetzen, die sie für eine Livesitzung bereitstellt, ohne sie neu zu erstellen. Beispielsweise kann eine Webseite verschiedene Tools anbieten, während der Benutzer navigiert, oder ein Client, der eine Sitzung übernimmt, kann eigene Tools mitbringen. Jedes SDK ersetzt den vollständigen Toolsatz des Clients und die zugehörigen Handler in einem Aufruf.

<!-- markdownlint-disable GHD046 GHD005 -->
<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

> **Experimentell.** Das Ersetzen des Tools kapselt den experimentellen `session.tools.set` RPC und erfordert eine Laufzeit, die ihn unterstützt.

## Tools dieses Clients ersetzen

Geben Sie den vollständigen Satz von Tools weiter, die dieser Client liefern sollte. Dies ersetzt die Tools, die der Client beim Erstellen oder Fortsetzen der Sitzung oder in einem früheren Ersatz bereitgestellt hat. Integrierte, MCP- und Plug-in-Tools sowie Tools, die von anderen Clients, die mit derselben Sitzung verbunden sind, bereitgestellt werden, sind nicht betroffen. Übergeben Sie eine leere Liste, um alle Tools dieses Clients zu entfernen.

Tools werden genau so definiert, wie beim Erstellen einer Sitzung, und ein Tool ohne Handler verhält sich genauso wie dort.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
import { defineTool } from "@github/copilot-sdk";
import { z } from "zod";

const searchIssues = defineTool("search_issues", {
    description: "Search the issues shown on the current page",
    parameters: z.object({ query: z.string().describe("Search text") }),
    handler: async ({ query }) => findIssues(query),
});

// Supply only the tools the current page provides.
await session.setTools([searchIssues]);

// Remove all of this client's tools.
await session.setTools([]);
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
from pydantic import BaseModel, Field
from copilot.tools import define_tool

class SearchIssuesParams(BaseModel):
    query: str = Field(description="Search text")

@define_tool(description="Search the issues shown on the current page")
async def search_issues(params: SearchIssuesParams) -> str:
    return await find_issues(params.query)

# Supply only the tools the current page provides.
await session.set_tools([search_issues])

# Remove all of this client's tools.
await session.set_tools([])
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
type SearchIssuesParams struct {
    Query string `json:"query" jsonschema:"Search text"`
}

searchIssues := copilot.DefineTool(
    "search_issues",
    "Search the issues shown on the current page",
    func(params SearchIssuesParams, inv copilot.ToolInvocation) (string, error) {
        return findIssues(params.Query)
    },
)

// Supply only the tools the current page provides.
if err := session.SetTools(ctx, []copilot.Tool{searchIssues}); err != nil {
    log.Fatal(err)
}

// Remove all of this client's tools.
if err := session.SetTools(ctx, nil); err != nil {
    log.Fatal(err)
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
var searchIssues = CopilotTool.DefineTool(
    ([Description("Search text")] string query) => FindIssues(query),
    factoryOptions: new AIFunctionFactoryOptions
    {
        Name = "search_issues",
        Description = "Search the issues shown on the current page",
    });

// Supply only the tools the current page provides.
await session.SetToolsAsync([searchIssues]);

// Remove all of this client's tools.
await session.SetToolsAsync([]);
```

`SetToolsAsync` löst die `GHCP001` experimentelle Diagnosemeldung aus, die Sie mit `#pragma warning disable GHCP001` oder mit `<NoWarn>GHCP001</NoWarn>` auf Projektebene unterdrücken.

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

```java
var searchIssues = ToolDefinition.create(
    "search_issues",
    "Search the issues shown on the current page",
    Map.of(
        "type", "object",
        "properties", Map.of("query", Map.of("type", "string", "description", "Search text")),
        "required", List.of("query")),
    invocation -> CompletableFuture.completedFuture(
        findIssues((String) invocation.getArguments().get("query"))));

// Supply only the tools the current page provides.
session.setTools(List.of(searchIssues)).get();

// Remove all of this client's tools.
session.setTools(List.of()).get();
```

`setTools` ist `@CopilotExperimental`, so muss die verbrauchende Klasse oder Methode sich mit `@AllowCopilotExperimental` explizit aktivieren. Siehe [Verwenden experimenteller APIs](https://github.com/github/copilot-sdk/tree/main/java/README.md#using-experimental-apis).

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

<!-- docs-validate: skip -->

```rust
#[derive(Deserialize, JsonSchema)]
struct SearchIssuesParams {
    /// Search text
    query: String,
}

let search_issues = define_tool(
    "search_issues",
    "Search the issues shown on the current page",
    |_inv, params: SearchIssuesParams| async move {
        Ok(ToolResult::Text(find_issues(&params.query).await))
    },
);

// Supply only the tools the current page provides.
session.set_tools(vec![search_issues]).await?;

// Remove all of this client's tools.
session.set_tools(Vec::new()).await?;
```

</div>

</div>

## Wenn die neuen Tools wirksam werden

- **Modellanfragen.** Die Laufzeit bietet die neuen Tools aus der nächsten Modellanfrage des Agenten. Diese Anforderung kann Teil eines Ablaufs sein, der bereits im Gange ist.
- **Handler.** Sobald die Laufzeit den Ersatz akzeptiert, verwendet jeder Tool-Aufruf, den die Sitzung auslöst, die neuen Handler. Anfragen, die bereits ausgeführt werden, werden auf den Handlern abgeschlossen, die sie gestartet haben.
- **Ablehnung.** Wenn die Laufzeit den Ersatz ablehnt, schlägt der Aufruf fehl, und die vorherigen Tools und Handler bleiben vorhanden. Die Laufzeit lehnt Toolnamen mit ungültigen Zeichen und Namen ab, die bereits von einem anderen verbundenen Client bereitgestellt werden.
- **Bestellung.** Gleichzeitige Ersetzungen in derselben Sitzung werden einzeln angewendet, in der Reihenfolge, in der sie vorgenommen werden.
- **Stornierung.** In SDKs, die es Ihnen ermöglichen, den Aufruf abzubrechen, sendet das Abbrechen nichts, solange ein früherer Ersetzungsaufruf noch in Bearbeitung ist. Sobald die Anforderung gesendet wurde, beendet das Abbrechen nur die Wartezeit: Wenn die Laufzeit den Ersatz akzeptiert, werden die neuen Handler weiterhin wirksam.

## Ersetzen von Tools während eines Zuges

Eine Modellanforderung, die bereits in Bearbeitung ist, wurde mit den vorherigen Tools durchgeführt, sodass der Agent weiterhin ein Tool aufrufen kann, das Sie soeben entfernt haben. Die Sitzung beantwortet diesen Aufruf nicht, da ein anderer verbundener Client möglicherweise ein Tool mit demselben Namen bereitstellen könnte, sodass der Aufruf ausstehen kann, bis der Vorgang abgebrochen wird.

Wenn ein laufender Turn möglicherweise weiterhin ein Tool aufruft, das Sie entfernen, ersetzen Sie Tools, während die Sitzung im Leerlauf ist, z. B. nach dem `session.idle`-Ereignis, oder brechen Sie den Turn zuerst ab. Das Ersetzen des Handlers eines Tools unter demselben Namen ist während eines Ausführungszyklus sicher: Aufrufe, die weitergeleitet werden, nachdem die Laufzeit den Ersatz akzeptiert hat, verwenden den neuen Handler.

## SDK-Referenz

| SDK | Methode |
|---|---|
| TypeScript | `session.setTools(tools)` |
| Python | `await session.set_tools(tools)` |
| Gehen | `session.SetTools(ctx, tools)` |
| .NET | `await session.SetToolsAsync(tools, cancellationToken)` |
| Java | 
`session.setTools(tools)`, das einen `CompletableFuture<Void>` zurückgibt |
| Rust | `session.set_tools(tools).await` |