@schlenkr/ragents 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/server/src/config-definition.ts +24 -2
- package/apps/server/src/config.ts +0 -6
- package/apps/server/src/host-api.json +3 -10
- package/apps/server/src/host-api.ts +6 -7
- package/apps/server/src/plugin-build/build.ts +28 -5
- package/apps/server/src/plugin-build/plugin-description.ts +1 -1
- package/apps/server/src/plugin-build/typecheck.ts +2 -2
- package/apps/server/src/plugin-support/language-server/plugin.ts +8 -7
- package/apps/server/src/plugin-support/language-server/tools.ts +7 -6
- package/apps/server/src/plugin-support/model-aliases.ts +55 -25
- package/apps/server/src/plugin-support/plugin-folder.ts +2 -1
- package/apps/server/src/plugin-support/product-relay.ts +10 -2
- package/apps/server/src/plugin-support/workspace-sandbox-host.ts +18 -9
- package/apps/server/src/profile/bundle-manifest.ts +7 -3
- package/apps/server/src/profile/compose.ts +6 -0
- package/apps/server/src/profile/plugin-discovery.ts +6 -1
- package/apps/server/src/profile/provisioning.ts +6 -5
- package/apps/server/src/ragents/engine.ts +18 -12
- package/apps/server/src/ragents/host-services.ts +4 -0
- package/apps/server/src/ragents/session.ts +1 -1
- package/apps/server/src/server.ts +1 -0
- package/apps/server/tsconfig.json +2 -0
- package/apps/web/dist/assets/{highlighted-body-KPVGNVTW-CFhTJEmH.js → highlighted-body-KPVGNVTW-xXXhTDbh.js} +1 -1
- package/apps/web/dist/assets/{main-DlzW4t4c.js → main-C7JeZFjs.js} +1 -1
- package/apps/web/dist/assets/{mermaid-HWGCJPDP-kxkB991i.js → mermaid-HWGCJPDP-DfsU5ofC.js} +2 -2
- package/apps/web/dist/assets/{runPanel-BJEFQ__w.js → runPanel-ZT6TPDLM.js} +1 -1
- package/apps/web/dist/help/guide-clients.html +14 -6
- package/apps/web/dist/help/guide-clients.md +14 -6
- package/apps/web/dist/help/guide-distributed.html +12 -4
- package/apps/web/dist/help/guide-distributed.md +12 -4
- package/apps/web/dist/help/guide-getting-started.html +12 -8
- package/apps/web/dist/help/guide-getting-started.md +12 -8
- package/apps/web/dist/help/guide-plugins.html +6 -2
- package/apps/web/dist/help/guide-plugins.md +6 -2
- package/apps/web/dist/help/guide-runtime.html +2 -1
- package/apps/web/dist/help/guide-runtime.md +2 -1
- package/apps/web/dist/help/index.html +3328 -1135
- package/apps/web/dist/host-web.json +4 -4
- package/apps/web/dist/index.html +2 -2
- package/apps/web/dist/run-panel.html +2 -2
- package/apps/web/src/StartTiles.tsx +1 -1
- package/bundles/ragents.activity/ragents-bundle.json +3 -3
- package/bundles/ragents.actor-programs/ragents-bundle.json +3 -3
- package/bundles/ragents.ask/ragents-bundle.json +4 -4
- package/bundles/ragents.ask/server/index.js +42 -11
- package/bundles/ragents.ask/server/index.js.map +3 -3
- package/bundles/ragents.ask/web/chunks/chunk-WFN4374U.js +2 -0
- package/bundles/ragents.ask/web/chunks/chunk-WFN4374U.js.map +7 -0
- package/bundles/ragents.ask/web/classes.json +1 -1
- package/bundles/ragents.ask/web/exports/ask-payload.js +1 -1
- package/bundles/ragents.ask/web/index.js +1 -1
- package/bundles/ragents.ask/web/index.js.map +3 -3
- package/bundles/ragents.browser/executor/index.mjs +357 -0
- package/bundles/ragents.browser/executor/index.mjs.map +7 -0
- package/bundles/ragents.browser/ragents-bundle.json +5 -8
- package/bundles/ragents.browser/server/chunks/{chunk-2GKLLCBE.js → chunk-CWLX4VA5.js} +1 -1
- package/bundles/ragents.browser/server/chunks/chunk-CWLX4VA5.js.map +7 -0
- package/bundles/ragents.browser/server/exports/server/contract.js +1 -1
- package/bundles/ragents.browser/server/index.js +20 -9
- package/bundles/ragents.browser/server/index.js.map +4 -4
- package/bundles/ragents.documents/ragents-bundle.json +3 -3
- package/bundles/ragents.lsp-fsharp/executor/index.mjs +68 -0
- package/bundles/ragents.lsp-fsharp/executor/index.mjs.map +7 -0
- package/bundles/ragents.lsp-fsharp/ragents-bundle.json +5 -9
- package/bundles/ragents.lsp-fsharp/server/index.js +21 -6
- package/bundles/ragents.lsp-fsharp/server/index.js.map +4 -4
- package/bundles/ragents.lsp-roslyn/executor/index.mjs +68 -0
- package/bundles/ragents.lsp-roslyn/executor/index.mjs.map +7 -0
- package/bundles/ragents.lsp-roslyn/ragents-bundle.json +6 -8
- package/bundles/ragents.lsp-roslyn/server/index.js +54 -15
- package/bundles/ragents.lsp-roslyn/server/index.js.map +4 -4
- package/bundles/ragents.lsp-typescript/executor/index.mjs +49 -0
- package/bundles/ragents.lsp-typescript/executor/index.mjs.map +7 -0
- package/bundles/ragents.lsp-typescript/ragents-bundle.json +5 -7
- package/bundles/ragents.lsp-typescript/server/index.js +22 -2
- package/bundles/ragents.lsp-typescript/server/index.js.map +3 -3
- package/bundles/ragents.model-relay/ragents-bundle.json +4 -4
- package/bundles/ragents.model-relay/server/index.js +3 -2
- package/bundles/ragents.model-relay/server/index.js.map +2 -2
- package/bundles/ragents.orchestration/ragents-bundle.json +3 -3
- package/bundles/ragents.overseer/ragents-bundle.json +3 -3
- package/bundles/ragents.processes/ragents-bundle.json +3 -3
- package/bundles/ragents.product/ragents-bundle.json +3 -3
- package/bundles/ragents.profile-distribution/ragents-bundle.json +4 -4
- package/bundles/ragents.profile-distribution/server/index.js +1 -1
- package/bundles/ragents.profile-distribution/server/index.js.map +2 -2
- package/bundles/ragents.reference/ragents-bundle.json +3 -3
- package/bundles/ragents.todo/ragents-bundle.json +3 -3
- package/bundles/ragents.transcript/ragents-bundle.json +3 -3
- package/bundles/ragents.watch/ragents-bundle.json +3 -3
- package/bundles/ragents.workspace/ragents-bundle.json +11 -5
- package/bundles/ragents.workspace/server/index.js +101 -28
- package/bundles/ragents.workspace/server/index.js.map +3 -3
- package/bundles/ragents.workspace/web/classes.json +1 -1
- package/bundles/ragents.workspace/web/index.js +1 -1
- package/bundles/ragents.workspace/web/index.js.map +3 -3
- package/package.json +2 -2
- package/packages/agent/dist/core/agent-settings.d.ts +1 -7
- package/packages/agent/dist/core/compaction/compaction.d.ts +17 -13
- package/packages/agent/dist/core/model-runtime.d.ts +5 -4
- package/packages/agent/dist/core/provider-composer.d.ts +2 -1
- package/packages/agent/dist/core/tools/bash.d.ts +9 -3
- package/packages/agent/dist/index.d.ts +1 -1
- package/packages/agent/src/core/agent-settings.ts +1 -4
- package/packages/agent/src/core/compaction/compaction.ts +68 -30
- package/packages/agent/src/core/model-runtime.ts +12 -5
- package/packages/agent/src/core/provider-composer.ts +5 -0
- package/packages/agent/src/core/tools/bash.ts +36 -30
- package/packages/agent/src/index.ts +3 -0
- package/packages/ai/dist/types.d.ts +11 -0
- package/packages/ai/src/types.ts +12 -0
- package/packages/ragents/src/agents/plugins.ts +5 -0
- package/packages/ragents/src/domain/event-semantics.ts +3 -0
- package/packages/ragents/src/domain/event-validation.ts +15 -2
- package/packages/ragents/src/domain/events.ts +3 -0
- package/packages/ragents/src/domain/model.ts +2 -0
- package/packages/ragents/src/domain/projection.ts +1 -0
- package/packages/ragents/src/drivers/agent-runtime.ts +1 -1
- package/packages/ragents/src/drivers/agent-turn.ts +8 -6
- package/packages/ragents/src/index.ts +1 -0
- package/packages/ragents/src/plugin-host.ts +58 -10
- package/packages/ragents/src/plugin-types.ts +7 -2
- package/packages/ragents/src/runtime/decisions/inputs.ts +6 -2
- package/packages/ragents/src/runtime/journal-storage.ts +5 -4
- package/packages/workspace-executor/package.json +0 -1
- package/packages/workspace-executor/src/bash-launch.ts +56 -10
- package/packages/workspace-executor/src/context.ts +4 -0
- package/packages/workspace-executor/src/contributions.ts +150 -0
- package/packages/workspace-executor/src/executor.ts +1 -1
- package/packages/workspace-executor/src/index.ts +16 -19
- package/packages/workspace-executor/src/language-server/host.ts +3 -0
- package/packages/workspace-executor/src/language-server/module.ts +12 -2
- package/packages/workspace-executor/src/language-server/roots.ts +0 -5
- package/packages/workspace-executor/src/modules.ts +7 -6
- package/packages/workspace-executor/src/sandbox-tools.ts +3 -9
- package/packages/workspace-executor/src/shell-platform.ts +14 -3
- package/packages/workspace-executor/src/tools.ts +0 -3
- package/plugins/ragents.ask/ask-payload.ts +9 -0
- package/plugins/ragents.ask/server/ask-service.ts +53 -13
- package/plugins/ragents.ask/web/AskActionView.tsx +3 -2
- package/plugins/ragents.browser/executor/index.ts +5 -0
- package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/module.ts +25 -31
- package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/playwright.ts +9 -23
- package/plugins/ragents.browser/provision.ts +1 -1
- package/plugins/ragents.browser/server/browser.ts +3 -3
- package/plugins/ragents.browser/server/contract.ts +2 -2
- package/plugins/ragents.browser/server/index.ts +1 -1
- package/plugins/ragents.lsp-fsharp/executor.ts +80 -0
- package/plugins/ragents.lsp-fsharp/provision.ts +1 -1
- package/plugins/ragents.lsp-fsharp/server/index.ts +2 -2
- package/plugins/ragents.lsp-roslyn/executor.ts +64 -0
- package/plugins/ragents.lsp-roslyn/provision.ts +1 -1
- package/plugins/ragents.lsp-roslyn/server/index.ts +28 -5
- package/plugins/ragents.lsp-roslyn/server/solution-on-start.ts +18 -6
- package/plugins/ragents.lsp-typescript/executor.ts +50 -0
- package/plugins/ragents.lsp-typescript/server/index.ts +2 -2
- package/plugins/ragents.model-relay/server/config.ts +1 -1
- package/plugins/ragents.model-relay/server/relay.ts +4 -2
- package/plugins/ragents.profile-distribution/server/archive.ts +2 -1
- package/plugins/ragents.workspace/client/workspace-client.ts +111 -28
- package/plugins/ragents.workspace/contract.ts +33 -2
- package/plugins/ragents.workspace/server/binding.ts +10 -4
- package/plugins/ragents.workspace/server/clients.ts +56 -9
- package/plugins/ragents.workspace/server/config.ts +9 -0
- package/plugins/ragents.workspace/server/index.ts +13 -4
- package/plugins/ragents.workspace/server/runtime.ts +10 -0
- package/plugins/ragents.workspace/server/shell-platform.ts +6 -5
- package/plugins/ragents.workspace/web/WorkspaceBinding.tsx +1 -1
- package/ragents.config.core.ts +4 -1
- package/ragents.config.showcase.ts +4 -1
- package/scripts/agent/journal.ts +3 -1
- package/scripts/package/build-package.ts +3 -1
- package/scripts/package/publish-package.ts +4 -3
- package/scripts/provision/run-provision.ts +2 -2
- package/scripts/workspace-client/run-workspace-client.ts +7 -4
- package/apps/web/dist/help/screenshots/release-checklist-vscode.png +0 -0
- package/apps/web/dist/help/screenshots/release-checklist-web.png +0 -0
- package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js +0 -2
- package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js.map +0 -7
- package/bundles/ragents.browser/server/chunks/chunk-2GKLLCBE.js.map +0 -7
- package/packages/workspace-executor/src/language-server/adapters/fsharp.ts +0 -60
- package/packages/workspace-executor/src/language-server/adapters/index.ts +0 -7
- package/packages/workspace-executor/src/language-server/adapters/roslyn.ts +0 -56
- package/packages/workspace-executor/src/language-server/adapters/typescript.ts +0 -74
- package/packages/workspace-executor/src/language-server/solution.ts +0 -13
- /package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/contract.ts +0 -0
- /package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/pages.ts +0 -0
package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/playwright.ts
RENAMED
|
@@ -1,30 +1,16 @@
|
|
|
1
1
|
import { constants } from "node:fs";
|
|
2
2
|
import { access } from "node:fs/promises";
|
|
3
|
-
import {
|
|
4
|
-
import { homedir } from "node:os";
|
|
5
|
-
import path from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
6
4
|
import type { Browser } from "playwright-core";
|
|
7
|
-
import {
|
|
8
|
-
import { safeProcessEnvironment } from "../safe-environment.js";
|
|
5
|
+
import type { WorkspaceExecutorMachine } from "@ragents/workspace-executor";
|
|
9
6
|
import { BROWSER_EXECUTABLE_VARIABLE } from "./contract.js";
|
|
10
7
|
|
|
11
8
|
type Playwright = typeof import("playwright-core");
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (!hostRoot) {
|
|
18
|
-
throw new Error("Für die Browserprüfung ist auf diesem Rechner kein Host bekannt, aus dem sich playwright-core auflösen "
|
|
19
|
-
+ "ließe. Ein Arbeitsplatz bekommt ihn mit der ersten Verbindung zu einem verteilenden Server oder über die "
|
|
20
|
-
+ "Einstellung ragents.hostPath");
|
|
21
|
-
}
|
|
22
|
-
const load = createRequire(path.join(hostRoot, "package.json"));
|
|
23
|
-
try {
|
|
24
|
-
return load("playwright-core") as Playwright;
|
|
25
|
-
} catch (cause) {
|
|
26
|
-
throw new Error(`playwright-core liegt nicht im Host ${hostRoot}: ${messageOf(cause)}`);
|
|
27
|
-
}
|
|
10
|
+
/** playwright-core liegt in den node_modules des Hosts dieser Maschine und wird erst im Aufruf geladen, nie mit dem Beitrag. */
|
|
11
|
+
export const hostPlaywright = async (machine: WorkspaceExecutorMachine, hostRoot: string | undefined): Promise<Playwright> => {
|
|
12
|
+
const loaded = await import(pathToFileURL(machine.hostPackageFile(hostRoot, "playwright-core")).href) as { default: Playwright };
|
|
13
|
+
return loaded.default;
|
|
28
14
|
};
|
|
29
15
|
|
|
30
16
|
/** Der Chrome dieser Maschine: der aus ihrer Umgebung, sonst das Chromium, das die Provisionierung für playwright-core holt. */
|
|
@@ -41,12 +27,12 @@ export const browserExecutable = async (playwright: Playwright, environment: Nod
|
|
|
41
27
|
};
|
|
42
28
|
|
|
43
29
|
/** Startet Chrome headless mit der Umgebung dieser Maschine und dem Marker des Runs, damit die Prozessanzeige ihn zuordnet. */
|
|
44
|
-
export const launchChromium = async (hostRoot: string | undefined, runId: string, timeoutMs: number): Promise<Browser> => {
|
|
45
|
-
const playwright = hostPlaywright(hostRoot);
|
|
30
|
+
export const launchChromium = async (machine: WorkspaceExecutorMachine, hostRoot: string | undefined, runId: string, timeoutMs: number): Promise<Browser> => {
|
|
31
|
+
const playwright = await hostPlaywright(machine, hostRoot);
|
|
46
32
|
return playwright.chromium.launch({
|
|
47
33
|
executablePath: await browserExecutable(playwright),
|
|
48
34
|
headless: true,
|
|
49
35
|
timeout: timeoutMs,
|
|
50
|
-
env:
|
|
36
|
+
env: machine.processEnvironment(runId),
|
|
51
37
|
});
|
|
52
38
|
};
|
|
@@ -2,13 +2,13 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { access, constants } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { chromium } from "playwright-core";
|
|
5
|
-
import { BROWSER_EXECUTABLE_VARIABLE } from "@ragents/workspace-executor";
|
|
6
5
|
import {
|
|
7
6
|
hostPackageFolder,
|
|
8
7
|
provisionGap,
|
|
9
8
|
provisionReady,
|
|
10
9
|
type PluginProvision,
|
|
11
10
|
} from "@ragents/host/plugin-support/provision.js";
|
|
11
|
+
import { BROWSER_EXECUTABLE_VARIABLE } from "./executor/contract.js";
|
|
12
12
|
|
|
13
13
|
const executable = async (file: string): Promise<boolean> => access(file, constants.X_OK).then(() => true, () => false);
|
|
14
14
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import type { SandboxServices } from "@ragents/host/plugin-support/workspace-sandbox-host.js";
|
|
5
|
+
import { documentsApiPrefix } from "@ragents/plugins/ragents.documents/contract.js";
|
|
4
6
|
import {
|
|
5
7
|
BROWSER_OPERATIONS,
|
|
6
8
|
type BrowserCheck,
|
|
@@ -10,9 +12,7 @@ import {
|
|
|
10
12
|
type BrowserStep,
|
|
11
13
|
type BrowserTarget,
|
|
12
14
|
type BrowserViewport,
|
|
13
|
-
} from "
|
|
14
|
-
import type { SandboxServices } from "@ragents/host/plugin-support/workspace-sandbox-host.js";
|
|
15
|
-
import { documentsApiPrefix } from "@ragents/plugins/ragents.documents/contract.js";
|
|
15
|
+
} from "../executor/contract.js";
|
|
16
16
|
import type { BrowserCallOptions, BrowserEvidence, BrowserRuntime } from "./contract.js";
|
|
17
17
|
|
|
18
18
|
export const DEFAULT_VIEWPORT: BrowserViewport = { width: 1920, height: 1080 };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { serviceToken } from "@ragents/engine";
|
|
2
|
-
import type { BrowserSnapshot } from "
|
|
2
|
+
import type { BrowserSnapshot } from "../executor/contract.js";
|
|
3
3
|
|
|
4
|
-
export type { BrowserSnapshot, BrowserTarget } from "
|
|
4
|
+
export type { BrowserSnapshot, BrowserTarget } from "../executor/contract.js";
|
|
5
5
|
|
|
6
6
|
export interface BrowserEvidence {
|
|
7
7
|
checkedAt?: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { RAgentsPlugin } from "@ragents/engine";
|
|
2
|
-
import { BROWSER_EXECUTABLE_VARIABLE } from "@ragents/workspace-executor";
|
|
3
2
|
import type { PluginModule } from "@ragents/host/plugin-support/plugin-module.js";
|
|
4
3
|
import { sandboxServicesToken } from "@ragents/host/plugin-support/workspace-sandbox-host.js";
|
|
5
4
|
import { documentStoreToken } from "@ragents/host/ragents/document-store.js";
|
|
5
|
+
import { BROWSER_EXECUTABLE_VARIABLE } from "../executor/contract.js";
|
|
6
6
|
import { RunBrowser } from "./browser.js";
|
|
7
7
|
import { browserRuntimeToken } from "./contract.js";
|
|
8
8
|
import { createBrowserFunctions, createBrowserImageContribution } from "./tools.js";
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import type { LanguageServerDescription, WorkspaceExecutorContribution } from "@ragents/workspace-executor";
|
|
6
|
+
|
|
7
|
+
export const FSHARP_SERVER_VARIABLE = "FSHARP_LANGUAGE_SERVER";
|
|
8
|
+
export const FSHARP_SERVER_FILE = "fsautocomplete/fsautocomplete.dll";
|
|
9
|
+
|
|
10
|
+
const languages = { ".fs": "fsharp", ".fsi": "fsharp", ".fsx": "fsharp" } as const;
|
|
11
|
+
|
|
12
|
+
export const fsharpLanguageServer: LanguageServerDescription = {
|
|
13
|
+
id: "fsharp",
|
|
14
|
+
label: "FSAC",
|
|
15
|
+
languages,
|
|
16
|
+
rootDescription: "the .sln file (or a single .fsproj)",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const PROJECT_LINE = /^Project\("\{[^}]+\}"\)\s*=\s*"[^"]*",\s*"([^"]+)"/gm;
|
|
20
|
+
|
|
21
|
+
/** Die Projekte einer .sln, aufgelöst neben ihr; Ordnereinträge der Solution zählen nicht. */
|
|
22
|
+
export const solutionProjects = async (solutionFile: string): Promise<string[]> => {
|
|
23
|
+
const text = await readFile(solutionFile, "utf8");
|
|
24
|
+
const directory = path.dirname(solutionFile);
|
|
25
|
+
return [...text.matchAll(PROJECT_LINE)]
|
|
26
|
+
.map((match) => match[1].replaceAll("\\", "/"))
|
|
27
|
+
.filter((relative) => /\.[a-z]+proj$/i.test(relative))
|
|
28
|
+
.map((relative) => path.resolve(directory, relative));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const dotnetCommand = (server: string, args: readonly string[]): { command: string; args: string[] } =>
|
|
32
|
+
server.toLowerCase().endsWith(".dll")
|
|
33
|
+
? { command: "dotnet", args: [server, ...args] }
|
|
34
|
+
: { command: server, args: [...args] };
|
|
35
|
+
|
|
36
|
+
const serverPath = (toolsDirectory: string): string => {
|
|
37
|
+
const configured = process.env[FSHARP_SERVER_VARIABLE];
|
|
38
|
+
if (configured) return configured;
|
|
39
|
+
const provisioned = path.join(toolsDirectory, ...FSHARP_SERVER_FILE.split("/"));
|
|
40
|
+
if (existsSync(provisioned)) return provisioned;
|
|
41
|
+
throw new Error("fsautocomplete gibt es auf diesem Rechner nicht: weder "
|
|
42
|
+
+ `${FSHARP_SERVER_VARIABLE} gesetzt noch ${provisioned} vorhanden. Ein Arbeitsplatz holt es mit `
|
|
43
|
+
+ `pnpm provision --workspace, ein Server über pnpm provision <profil>; ${FSHARP_SERVER_VARIABLE} übersteuert beides`);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const contentOf = (params: unknown): string => (params as { content?: string } | undefined)?.content ?? "";
|
|
47
|
+
|
|
48
|
+
export const executor: WorkspaceExecutorContribution = (machine) => ({
|
|
49
|
+
languageServers: [{
|
|
50
|
+
...fsharpLanguageServer,
|
|
51
|
+
resolveRoot: (workspaceRoot, root) => machine.resolveRootFile(workspaceRoot, root, [".sln", ".fsproj"]),
|
|
52
|
+
rootDirectory: (root) => path.dirname(root),
|
|
53
|
+
launch: async (context, root) => ({
|
|
54
|
+
label: "FSAC",
|
|
55
|
+
...dotnetCommand(serverPath(machine.toolsDirectory), ["--state-directory", path.join(context.logDirectory, "fsautocomplete")]),
|
|
56
|
+
cwd: path.dirname(root),
|
|
57
|
+
env: context.env,
|
|
58
|
+
uid: context.uid,
|
|
59
|
+
gid: context.gid,
|
|
60
|
+
rootUri: pathToFileURL(path.dirname(root)).href,
|
|
61
|
+
initializationOptions: { AutomaticWorkspaceInit: false },
|
|
62
|
+
languages,
|
|
63
|
+
}),
|
|
64
|
+
open: async (session, root, timeoutMs) => {
|
|
65
|
+
const projects = root.toLowerCase().endsWith(".sln")
|
|
66
|
+
? (await solutionProjects(root)).filter((project) => project.toLowerCase().endsWith(".fsproj"))
|
|
67
|
+
: [root];
|
|
68
|
+
if (projects.length === 0) throw new Error(`${path.basename(root)} enthält keine F#-Projekte`);
|
|
69
|
+
const finished = session.waitForNotification(timeoutMs, "Projekte geladen", (method, params) =>
|
|
70
|
+
method === "fsharp/notifyWorkspace"
|
|
71
|
+
&& contentOf(params).includes("\"workspaceLoad\"")
|
|
72
|
+
&& contentOf(params).includes("\"finished\""));
|
|
73
|
+
await session.request("fsharp/workspaceLoad", {
|
|
74
|
+
textDocuments: projects.map((project) => ({ uri: pathToFileURL(project).href })),
|
|
75
|
+
});
|
|
76
|
+
await finished;
|
|
77
|
+
return `${projects.length} F#-Projekt${projects.length === 1 ? "" : "e"} aus ${path.basename(root)} geladen`;
|
|
78
|
+
},
|
|
79
|
+
}],
|
|
80
|
+
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { stat } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { FSHARP_SERVER_FILE } from "@ragents/workspace-executor";
|
|
4
3
|
import {
|
|
5
4
|
DOTNET_INSTRUCTION,
|
|
6
5
|
downloadArchive,
|
|
@@ -15,6 +14,7 @@ import {
|
|
|
15
14
|
type PluginProvision,
|
|
16
15
|
type ProvisionState,
|
|
17
16
|
} from "@ragents/host/plugin-support/provision.js";
|
|
17
|
+
import { FSHARP_SERVER_FILE } from "./executor.js";
|
|
18
18
|
|
|
19
19
|
export const FSAUTOCOMPLETE_VERSION = "0.83.0";
|
|
20
20
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { fsharpAdapter, FSHARP_SERVER_VARIABLE } from "@ragents/workspace-executor";
|
|
2
1
|
import { createLanguageServerPlugin } from "@ragents/host/plugin-support/language-server/plugin.js";
|
|
3
2
|
import type { PluginModule } from "@ragents/host/plugin-support/plugin-module.js";
|
|
3
|
+
import { fsharpLanguageServer, FSHARP_SERVER_VARIABLE } from "../executor.js";
|
|
4
4
|
|
|
5
5
|
export const fsharpConfigDescriptors = [
|
|
6
6
|
{ key: FSHARP_SERVER_VARIABLE, source: "environment" },
|
|
@@ -9,7 +9,7 @@ export const fsharpConfigDescriptors = [
|
|
|
9
9
|
export const plugin: PluginModule = {
|
|
10
10
|
create: () => createLanguageServerPlugin({
|
|
11
11
|
id: "ragents.lsp-fsharp",
|
|
12
|
-
|
|
12
|
+
languageServer: fsharpLanguageServer,
|
|
13
13
|
tabLabel: "F#",
|
|
14
14
|
configDescriptors: fsharpConfigDescriptors,
|
|
15
15
|
}),
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import type { LanguageServerDescription, WorkspaceExecutorContribution } from "@ragents/workspace-executor";
|
|
5
|
+
|
|
6
|
+
export const ROSLYN_SERVER_VARIABLE = "ROSLYN_LANGUAGE_SERVER";
|
|
7
|
+
export const ROSLYN_SERVER_FILE = "roslyn/Microsoft.CodeAnalysis.LanguageServer.dll";
|
|
8
|
+
|
|
9
|
+
const languages = { ".cs": "csharp" } as const;
|
|
10
|
+
|
|
11
|
+
export const roslynLanguageServer: LanguageServerDescription = {
|
|
12
|
+
id: "roslyn",
|
|
13
|
+
label: "Roslyn",
|
|
14
|
+
languages,
|
|
15
|
+
rootDescription: "the .sln file (or a single .csproj)",
|
|
16
|
+
solutionExtensions: [".sln", ".slnx"],
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const dotnetCommand = (server: string, args: readonly string[]): { command: string; args: string[] } =>
|
|
20
|
+
server.toLowerCase().endsWith(".dll")
|
|
21
|
+
? { command: "dotnet", args: [server, ...args] }
|
|
22
|
+
: { command: server, args: [...args] };
|
|
23
|
+
|
|
24
|
+
const serverPath = (toolsDirectory: string): string => {
|
|
25
|
+
const configured = process.env[ROSLYN_SERVER_VARIABLE];
|
|
26
|
+
if (configured) return configured;
|
|
27
|
+
const provisioned = path.join(toolsDirectory, ...ROSLYN_SERVER_FILE.split("/"));
|
|
28
|
+
if (existsSync(provisioned)) return provisioned;
|
|
29
|
+
throw new Error("Microsoft.CodeAnalysis.LanguageServer gibt es auf diesem Rechner nicht: weder "
|
|
30
|
+
+ `${ROSLYN_SERVER_VARIABLE} gesetzt noch ${provisioned} vorhanden. Ein Arbeitsplatz holt ihn mit `
|
|
31
|
+
+ `pnpm provision --workspace, ein Server über pnpm provision <profil>; ${ROSLYN_SERVER_VARIABLE} übersteuert beides`);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const executor: WorkspaceExecutorContribution = (machine) => ({
|
|
35
|
+
languageServers: [{
|
|
36
|
+
...roslynLanguageServer,
|
|
37
|
+
resolveRoot: (workspaceRoot, root) => machine.resolveRootFile(workspaceRoot, root, [".sln", ".slnx", ".csproj"]),
|
|
38
|
+
rootDirectory: (root) => path.dirname(root),
|
|
39
|
+
launch: async (context, root) => ({
|
|
40
|
+
label: "Roslyn",
|
|
41
|
+
...dotnetCommand(serverPath(machine.toolsDirectory), [
|
|
42
|
+
"--stdio",
|
|
43
|
+
"--logLevel", "Warning",
|
|
44
|
+
"--extensionLogDirectory", path.join(context.logDirectory, "roslyn-logs"),
|
|
45
|
+
]),
|
|
46
|
+
cwd: path.dirname(root),
|
|
47
|
+
env: context.env,
|
|
48
|
+
uid: context.uid,
|
|
49
|
+
gid: context.gid,
|
|
50
|
+
rootUri: pathToFileURL(path.dirname(root)).href,
|
|
51
|
+
languages,
|
|
52
|
+
newFileSettleMs: 2_000,
|
|
53
|
+
}),
|
|
54
|
+
open: async (session, root, timeoutMs) => {
|
|
55
|
+
const uri = pathToFileURL(root).href;
|
|
56
|
+
const loaded = session.waitForNotification(timeoutMs, "Projekte geladen",
|
|
57
|
+
(method) => method === "workspace/projectInitializationComplete");
|
|
58
|
+
if (root.toLowerCase().endsWith(".csproj")) session.notify("project/open", { projects: [uri] });
|
|
59
|
+
else session.notify("solution/open", { solution: uri });
|
|
60
|
+
await loaded;
|
|
61
|
+
return `${path.basename(root)} geladen`;
|
|
62
|
+
},
|
|
63
|
+
}],
|
|
64
|
+
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { stat } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { ROSLYN_SERVER_FILE } from "@ragents/workspace-executor";
|
|
4
3
|
import {
|
|
5
4
|
DOTNET_INSTRUCTION,
|
|
6
5
|
downloadArchive,
|
|
@@ -14,6 +13,7 @@ import {
|
|
|
14
13
|
type PluginProvision,
|
|
15
14
|
type ProvisionState,
|
|
16
15
|
} from "@ragents/host/plugin-support/provision.js";
|
|
16
|
+
import { ROSLYN_SERVER_FILE } from "./executor.js";
|
|
17
17
|
|
|
18
18
|
export const ROSLYN_VERSION = "5.4.0-2.26179.14";
|
|
19
19
|
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from "node:path";
|
|
2
2
|
import { declaredEnvironment } from "@ragents/host/plugin-support/plugin-config.js";
|
|
3
3
|
import { createLanguageServerPlugin } from "@ragents/host/plugin-support/language-server/plugin.js";
|
|
4
4
|
import type { PluginModule } from "@ragents/host/plugin-support/plugin-module.js";
|
|
5
5
|
import { sandboxServicesToken } from "@ragents/host/plugin-support/workspace-sandbox-host.js";
|
|
6
6
|
import { runtimeProviderToken } from "@ragents/host/ragents/host-services.js";
|
|
7
7
|
import { askServiceToken } from "@ragents/plugins/ragents.ask/server/contract.js";
|
|
8
|
-
import {
|
|
8
|
+
import { roslynLanguageServer, ROSLYN_SERVER_VARIABLE } from "../executor.js";
|
|
9
|
+
import {
|
|
10
|
+
createSolutionOnStart,
|
|
11
|
+
SOLUTION_ON_START_VARIABLE,
|
|
12
|
+
SOLUTION_PREFERRED_VARIABLE,
|
|
13
|
+
type SolutionOnStart,
|
|
14
|
+
} from "./solution-on-start.js";
|
|
9
15
|
|
|
10
16
|
export const roslynConfigDescriptors = [
|
|
11
17
|
{ key: ROSLYN_SERVER_VARIABLE, source: "environment" },
|
|
12
18
|
{ key: SOLUTION_ON_START_VARIABLE, source: "environment" },
|
|
19
|
+
{ key: SOLUTION_PREFERRED_VARIABLE, source: "environment" },
|
|
13
20
|
] as const;
|
|
14
21
|
|
|
15
22
|
const PLUGIN_ID = "ragents.lsp-roslyn";
|
|
@@ -25,13 +32,26 @@ export const solutionOnStart = (): boolean => {
|
|
|
25
32
|
return mode === "on";
|
|
26
33
|
};
|
|
27
34
|
|
|
35
|
+
/** Ein Pfad relativ zur Wurzel des Arbeitsbereichs, wie ihn `roslyn_solutions` nennt; ohne Laden beim Start hätte er keine Wirkung. */
|
|
36
|
+
export const preferredSolution = (loadOnStart: boolean): string | undefined => {
|
|
37
|
+
const preferred = env.optional(SOLUTION_PREFERRED_VARIABLE);
|
|
38
|
+
if (preferred === undefined) return undefined;
|
|
39
|
+
if (!loadOnStart) {
|
|
40
|
+
throw new Error(`${SOLUTION_PREFERRED_VARIABLE} in der Sektion ragents.lsp-roslyn verlangt ${SOLUTION_ON_START_VARIABLE}: "on"`);
|
|
41
|
+
}
|
|
42
|
+
if (preferred === "" || preferred.includes("\\") || path.win32.isAbsolute(preferred)) {
|
|
43
|
+
throw new Error(`${SOLUTION_PREFERRED_VARIABLE} in der Sektion ragents.lsp-roslyn ist ein Pfad relativ zum Arbeitsbereich mit Schrägstrichen, nicht "${preferred}"`);
|
|
44
|
+
}
|
|
45
|
+
return preferred;
|
|
46
|
+
};
|
|
47
|
+
|
|
28
48
|
export const plugin: PluginModule = {
|
|
29
49
|
requires: ["ragents.ask"],
|
|
30
50
|
create: () => {
|
|
31
51
|
let startup: SolutionOnStart | undefined;
|
|
32
52
|
const languageServer = createLanguageServerPlugin({
|
|
33
53
|
id: PLUGIN_ID,
|
|
34
|
-
|
|
54
|
+
languageServer: roslynLanguageServer,
|
|
35
55
|
configDescriptors: roslynConfigDescriptors,
|
|
36
56
|
onOpened: (runId) => startup?.opened(runId),
|
|
37
57
|
});
|
|
@@ -39,10 +59,13 @@ export const plugin: PluginModule = {
|
|
|
39
59
|
manifest: languageServer.manifest,
|
|
40
60
|
register: (host) => {
|
|
41
61
|
languageServer.register(host);
|
|
42
|
-
|
|
62
|
+
const loadOnStart = solutionOnStart();
|
|
63
|
+
const preferred = preferredSolution(loadOnStart);
|
|
64
|
+
if (!loadOnStart) return;
|
|
43
65
|
startup = createSolutionOnStart({
|
|
44
66
|
pluginId: PLUGIN_ID,
|
|
45
|
-
adapterId:
|
|
67
|
+
adapterId: roslynLanguageServer.id,
|
|
68
|
+
preferred,
|
|
46
69
|
sandbox: () => host.service(sandboxServicesToken),
|
|
47
70
|
runtime: () => host.service(runtimeProviderToken)(),
|
|
48
71
|
ask: () => host.service(askServiceToken),
|
|
@@ -8,6 +8,7 @@ import type { SandboxServices } from "@ragents/host/plugin-support/workspace-san
|
|
|
8
8
|
import { DISMISSED_ANSWER, type AskService } from "@ragents/plugins/ragents.ask/server/contract.js";
|
|
9
9
|
|
|
10
10
|
export const SOLUTION_ON_START_VARIABLE = "ROSLYN_SOLUTION_ON_START";
|
|
11
|
+
export const SOLUTION_PREFERRED_VARIABLE = "ROSLYN_SOLUTION_PREFERRED";
|
|
11
12
|
export const NO_SOLUTION = "Keine laden";
|
|
12
13
|
export const SOLUTION_QUESTION = "Welche Solution soll Roslyn für die Diagnostik laden?";
|
|
13
14
|
|
|
@@ -21,11 +22,21 @@ export type SolutionAnswer =
|
|
|
21
22
|
| { kind: "open"; path: string }
|
|
22
23
|
| { kind: "forward" };
|
|
23
24
|
|
|
24
|
-
/**
|
|
25
|
-
|
|
25
|
+
/** Die Vorgabe passt auch in einem Unterordner, etwa wenn der Arbeitsbereich der Ordner über dem Checkout ist. */
|
|
26
|
+
const matchesPreferred = (solution: string, preferred: string): boolean => {
|
|
27
|
+
const path = solution.toLowerCase();
|
|
28
|
+
const expected = preferred.toLowerCase();
|
|
29
|
+
return path === expected || path.endsWith(`/${expected}`);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/** Was jemand schon geöffnet hat oder gerade öffnet, bleibt ohne Frage und ohne zweites Laden; passt die Vorgabe, zählen nur die passenden Solutions. */
|
|
33
|
+
export const solutionStartStep = (listing: LanguageServerSolutions, preferred?: string): SolutionStartStep => {
|
|
26
34
|
if (listing.opened || listing.solutions.length === 0) return { kind: "none" };
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
const paths = listing.solutions.map((solution) => solution.path);
|
|
36
|
+
const matching = preferred === undefined ? [] : paths.filter((path) => matchesPreferred(path, preferred));
|
|
37
|
+
const candidates = matching.length > 0 ? matching : paths;
|
|
38
|
+
if (candidates.length === 1) return { kind: "open", path: candidates[0] };
|
|
39
|
+
return { kind: "ask", options: [...candidates, NO_SOLUTION] };
|
|
29
40
|
};
|
|
30
41
|
|
|
31
42
|
/** Eine frei formulierte Antwort bekommt der Koordinator, damit sie nicht verloren geht. */
|
|
@@ -38,6 +49,7 @@ export const solutionAnswer = (options: readonly string[], answer: string): Solu
|
|
|
38
49
|
export interface SolutionOnStartOptions {
|
|
39
50
|
pluginId: string;
|
|
40
51
|
adapterId: string;
|
|
52
|
+
preferred?: string;
|
|
41
53
|
sandbox: () => SandboxServices;
|
|
42
54
|
runtime: () => Orchestration;
|
|
43
55
|
ask: () => AskService;
|
|
@@ -45,7 +57,7 @@ export interface SolutionOnStartOptions {
|
|
|
45
57
|
|
|
46
58
|
const messageOf = (error: unknown): string => error instanceof Error ? error.message : String(error);
|
|
47
59
|
|
|
48
|
-
/** Lädt beim Start ohne Run-Script die einzige Solution oder fragt bei mehreren; der Merker im Journal lässt das je Run höchstens einmal zu. */
|
|
60
|
+
/** Lädt beim Start ohne Run-Script die Vorgabe oder die einzige Solution oder fragt bei mehreren; der Merker im Journal lässt das je Run höchstens einmal zu. */
|
|
49
61
|
export interface SolutionOnStart {
|
|
50
62
|
lifecycle: SessionLifecycleContribution;
|
|
51
63
|
/** Jemand hat eine Instanz geöffnet; eine noch offene Startfrage erledigt sich damit ohne Laden und ohne Input. */
|
|
@@ -78,7 +90,7 @@ export const createSolutionOnStart = (options: SolutionOnStartOptions): Solution
|
|
|
78
90
|
|
|
79
91
|
const begin = async (runId: string, ownerId: string, coordinatorId: string, signal: AbortSignal): Promise<{ rest: Promise<void> }> => {
|
|
80
92
|
const listing = await options.sandbox().execute(runId, languageServerSolutionsOperation(options.adapterId), null, { signal }) as LanguageServerSolutions;
|
|
81
|
-
const step = solutionStartStep(listing);
|
|
93
|
+
const step = solutionStartStep(listing, options.preferred);
|
|
82
94
|
if (step.kind === "none") return { rest: Promise.resolve() };
|
|
83
95
|
if (step.kind === "open") return { rest: load(runId, step.path, true, signal) };
|
|
84
96
|
const answer = options.ask().ask(
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { stat } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import type { LanguageServerDescription, WorkspaceExecutorContribution } from "@ragents/workspace-executor";
|
|
5
|
+
|
|
6
|
+
const languages = {
|
|
7
|
+
".ts": "typescript",
|
|
8
|
+
".tsx": "typescriptreact",
|
|
9
|
+
".mts": "typescript",
|
|
10
|
+
".cts": "typescript",
|
|
11
|
+
".js": "javascript",
|
|
12
|
+
".jsx": "javascriptreact",
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export const typescriptLanguageServer: LanguageServerDescription = {
|
|
16
|
+
id: "typescript",
|
|
17
|
+
label: "TypeScript",
|
|
18
|
+
languages,
|
|
19
|
+
rootDescription: "the directory whose tsconfig.json projects should be served (e.g. src)",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const hasWorkspaceTypeScript = (root: string): Promise<boolean> =>
|
|
23
|
+
stat(path.join(root, "node_modules", "typescript", "lib", "tsserver.js")).then((info) => info.isFile(), () => false);
|
|
24
|
+
|
|
25
|
+
/** Sprachserver und Compiler liegen in den node_modules des Hosts dieser Maschine; ohne Host gibt es sie hier nicht. */
|
|
26
|
+
export const executor: WorkspaceExecutorContribution = (machine) => ({
|
|
27
|
+
languageServers: [{
|
|
28
|
+
...typescriptLanguageServer,
|
|
29
|
+
resolveRoot: machine.resolveRootDirectory,
|
|
30
|
+
rootDirectory: (root) => root,
|
|
31
|
+
launch: async (context, root) => ({
|
|
32
|
+
label: "TypeScript",
|
|
33
|
+
command: process.execPath,
|
|
34
|
+
args: [machine.hostPackageFile(context.hostRoot, "typescript-language-server/lib/cli.mjs"), "--stdio"],
|
|
35
|
+
cwd: root,
|
|
36
|
+
// Im Extension-Host ist process.execPath Electron; ohne diese Variable startet es die Anwendung statt des Skripts.
|
|
37
|
+
env: { ...context.env, ELECTRON_RUN_AS_NODE: "1" },
|
|
38
|
+
uid: context.uid,
|
|
39
|
+
gid: context.gid,
|
|
40
|
+
rootUri: pathToFileURL(root).href,
|
|
41
|
+
initializationOptions: await hasWorkspaceTypeScript(root)
|
|
42
|
+
? {}
|
|
43
|
+
: { tsserver: { path: path.dirname(machine.hostPackageFile(context.hostRoot, "typescript")) } },
|
|
44
|
+
languages,
|
|
45
|
+
publishesOnlyChangedDiagnostics: true,
|
|
46
|
+
}),
|
|
47
|
+
open: async (_session, root) =>
|
|
48
|
+
`TypeScript-Server auf ${path.basename(root)} bereit; Projekte werden je Datei aus der nächsten tsconfig.json geladen`,
|
|
49
|
+
}],
|
|
50
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { typescriptAdapter } from "@ragents/workspace-executor";
|
|
2
1
|
import { createLanguageServerPlugin } from "@ragents/host/plugin-support/language-server/plugin.js";
|
|
3
2
|
import type { PluginModule } from "@ragents/host/plugin-support/plugin-module.js";
|
|
3
|
+
import { typescriptLanguageServer } from "../executor.js";
|
|
4
4
|
|
|
5
5
|
export const plugin: PluginModule = {
|
|
6
|
-
create: () => createLanguageServerPlugin({ id: "ragents.lsp-typescript",
|
|
6
|
+
create: () => createLanguageServerPlugin({ id: "ragents.lsp-typescript", languageServer: typescriptLanguageServer }),
|
|
7
7
|
};
|
|
@@ -2,7 +2,7 @@ import { configuredModelAliases, type ModelAlias } from "@ragents/host/plugin-su
|
|
|
2
2
|
|
|
3
3
|
/** Das Relay bietet die Aliasse des Profils an (MODEL_ALIASES im Abschnitt host), dieselben wie für die eigenen Runs. */
|
|
4
4
|
export const relayAliases = (aliases: readonly ModelAlias[]): readonly ModelAlias[] => {
|
|
5
|
-
if (aliases.length === 0) throw new Error("ragents.model-relay
|
|
5
|
+
if (aliases.length === 0) throw new Error("ragents.model-relay needs MODEL_ALIASES in the host section, a list of { alias, model, thinking?, compaction }");
|
|
6
6
|
return aliases;
|
|
7
7
|
};
|
|
8
8
|
|
|
@@ -18,6 +18,7 @@ export interface ResolvedAlias {
|
|
|
18
18
|
readonly alias: string;
|
|
19
19
|
readonly upstream: ModelUpstream;
|
|
20
20
|
readonly model: ModelUpstream["models"][number];
|
|
21
|
+
readonly compaction: ModelAlias["compaction"];
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
/** Jeder Alias muss auf einen konfigurierten Anbieter und ein Modell aus dessen Katalog zeigen. */
|
|
@@ -30,10 +31,10 @@ export const resolveAliases = (aliases: readonly ModelAlias[], upstreams: readon
|
|
|
30
31
|
}
|
|
31
32
|
const model = upstream.models.find((candidate) => candidate.id === entry.model);
|
|
32
33
|
if (!model) throw new Error(`MODEL_ALIASES: das Modell ${entry.model} hinter ${entry.alias} fehlt im Katalog von ${entry.upstream}`);
|
|
33
|
-
return { alias: entry.alias, upstream, model };
|
|
34
|
+
return { alias: entry.alias, upstream, model, compaction: entry.compaction };
|
|
34
35
|
});
|
|
35
36
|
|
|
36
|
-
/** Der Katalogeintrag nennt nur, was der Verbraucher für
|
|
37
|
+
/** Der Katalogeintrag nennt nur, was der Verbraucher für Draht und Kompaktierung braucht; Name, Anbieter und Kosten bleiben beim Server. */
|
|
37
38
|
export const catalogEntryOf = (resolved: ResolvedAlias) => ({
|
|
38
39
|
id: resolved.alias,
|
|
39
40
|
object: "model" as const,
|
|
@@ -44,6 +45,7 @@ export const catalogEntryOf = (resolved: ResolvedAlias) => ({
|
|
|
44
45
|
input: [...resolved.model.input],
|
|
45
46
|
contextWindow: resolved.model.contextWindow,
|
|
46
47
|
maxTokens: resolved.model.maxTokens,
|
|
48
|
+
compaction: resolved.compaction,
|
|
47
49
|
...(resolved.model.compat ? { compat: resolved.model.compat } : {}),
|
|
48
50
|
},
|
|
49
51
|
});
|
|
@@ -55,7 +55,8 @@ const checkSections = (source: string, raw: Record<string, unknown>, pluginIds:
|
|
|
55
55
|
if (isEnvironmentReference(entry) || isProvisionedReference(entry)) continue;
|
|
56
56
|
if (SECRET_KEY_PATTERN.test(key)) throw new Error(`${source}: ${section}.${key} ist ein Secret und muss als env("...") stehen`);
|
|
57
57
|
const valid = typeof entry === "string" || typeof entry === "number" || typeof entry === "boolean"
|
|
58
|
-
|| (Array.isArray(entry) && entry.every((item) => typeof item === "string"))
|
|
58
|
+
|| (Array.isArray(entry) && entry.every((item) => typeof item === "string"))
|
|
59
|
+
|| (Array.isArray(entry) && entry.every((item) => !!item && typeof item === "object" && !Array.isArray(item)));
|
|
59
60
|
if (!valid) throw new Error(`${source}: ${section}.${key} hat keinen gültigen Wert`);
|
|
60
61
|
if (typeof entry === "string" && /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(entry)) throw new Error(`${source}: ${section}.${key} verweist als Text auf die Umgebung; env("...") verwenden`);
|
|
61
62
|
}
|