@schlenkr/ragents 0.1.8 → 0.1.10
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/package.json +1 -1
- package/apps/server/src/access-projection.ts +6 -36
- package/apps/server/src/api/contracts.ts +5 -2
- package/apps/server/src/api/core-methods.ts +5 -3
- package/apps/server/src/config-definition.ts +24 -2
- package/apps/server/src/config-file.ts +1 -1
- package/apps/server/src/config.ts +0 -6
- package/apps/server/src/host-api.json +5 -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/process-sandbox.ts +16 -15
- 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/provider.ts +2 -2
- package/apps/server/src/ragents/engine.ts +2 -2
- package/apps/server/src/ragents/global-chat.ts +7 -1
- 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 +4 -1
- package/apps/server/tsconfig.json +2 -0
- package/apps/web/dist/assets/{highlighted-body-KPVGNVTW-xXXhTDbh.js → highlighted-body-KPVGNVTW-BO4wLQtE.js} +1 -1
- package/apps/web/dist/assets/main-DnnqWHkH.js +11 -0
- package/apps/web/dist/assets/mermaid-HWGCJPDP-BLLeth5_.js +568 -0
- package/apps/web/dist/assets/{runPanel-ZT6TPDLM.js → runPanel-DPm7s3KM.js} +2 -2
- package/apps/web/dist/help/guide-clients.html +26 -8
- package/apps/web/dist/help/guide-clients.md +27 -8
- 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 +4328 -1132
- package/apps/web/dist/help/mini-app.css +24 -0
- 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/package.json +1 -1
- package/apps/web/src/panel/ConnectionsPage.tsx +3 -0
- package/apps/web/src/panel/StartPage.tsx +3 -0
- package/apps/web/src/panel/contract.ts +7 -0
- package/bundles/ragents.activity/ragents-bundle.json +3 -3
- package/bundles/ragents.actor-programs/ragents-bundle.json +4 -4
- package/bundles/ragents.actor-programs/server/index.js +31 -3
- package/bundles/ragents.actor-programs/server/index.js.map +4 -4
- package/bundles/ragents.actor-programs/web/index.js.map +1 -1
- package/bundles/ragents.ask/ragents-bundle.json +4 -6
- 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-V7W3QDVS.js → chunk-MBRPS477.js} +2 -2
- package/bundles/ragents.ask/web/chunks/{chunk-V7W3QDVS.js.map → chunk-MBRPS477.js.map} +4 -4
- 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/exports/web/QuestionCard.js +1 -1
- package/bundles/ragents.ask/web/index.js +1 -1
- package/bundles/ragents.ask/web/index.js.map +4 -4
- 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 +4 -4
- package/bundles/ragents.orchestration/web/classes.json +1 -1
- package/bundles/ragents.orchestration/web/index.js +6 -6
- package/bundles/ragents.orchestration/web/index.js.map +3 -3
- package/bundles/ragents.overseer/ragents-bundle.json +4 -4
- package/bundles/ragents.overseer/server/index.js +1 -1
- package/bundles/ragents.overseer/server/index.js.map +2 -2
- 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 +105 -30
- 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 +3 -3
- 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/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 +46 -0
- package/packages/ragents/src/plugin-types.ts +19 -0
- 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/managed-process.ts +28 -0
- package/packages/workspace-executor/src/modules.ts +7 -6
- package/packages/workspace-executor/src/sandbox-tools.ts +12 -12
- package/packages/workspace-executor/src/shell-platform.ts +14 -3
- package/packages/workspace-executor/src/tools.ts +0 -3
- package/plugins/ragents.actor-programs/server/access-projections.ts +31 -0
- package/plugins/ragents.actor-programs/server/index.ts +2 -0
- 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.ask/web/index.tsx +0 -6
- 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.orchestration/web/ActorTile.tsx +1 -1
- package/plugins/ragents.orchestration/web/run-panel/RunPanel.tsx +8 -7
- package/plugins/ragents.orchestration/web/run-panel/sheet-status.ts +3 -3
- package/plugins/ragents.overseer/server/api.ts +2 -2
- package/plugins/ragents.profile-distribution/server/archive.ts +2 -1
- package/plugins/ragents.workspace/client/workspace-client.ts +128 -32
- 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 +12 -0
- package/plugins/ragents.workspace/server/index.ts +15 -5
- 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/provision/run-provision.ts +2 -2
- package/scripts/workspace-client/run-workspace-client.ts +7 -4
- package/apps/web/dist/assets/main-C7JeZFjs.js +0 -6
- package/apps/web/dist/assets/mermaid-HWGCJPDP-DfsU5ofC.js +0 -478
- 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/plugins/ragents.ask/web/QuestionSection.tsx +0 -48
- /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
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { aliasedModel, type ModelAlias as RuntimeModelAlias } from "@ragents/agent";
|
|
1
|
+
import { aliasedModel, compactionProblem, type ModelAlias as RuntimeModelAlias } from "@ragents/agent";
|
|
2
2
|
import { getSupportedThinkingLevels, type Api, type Model } from "@ragents/ai";
|
|
3
3
|
import { getBuiltinModels, type BuiltinProvider } from "@ragents/ai/providers/all";
|
|
4
4
|
import { isThinkingLevel, type ThinkingLevel } from "@ragents/engine";
|
|
5
5
|
import { declaredEnvironment } from "./plugin-config.js";
|
|
6
6
|
|
|
7
|
-
/** Ein Alias des Profils mit
|
|
7
|
+
/** Ein Alias des Profils mit Ziel und Kompaktierungswerten und optional der Denktiefe, die gilt, solange niemand eine andere wählt. */
|
|
8
8
|
export interface ModelAlias extends RuntimeModelAlias {
|
|
9
9
|
readonly thinking?: ThinkingLevel;
|
|
10
10
|
}
|
|
@@ -17,47 +17,77 @@ export const modelAliasEnvDescriptors = [
|
|
|
17
17
|
] as const;
|
|
18
18
|
|
|
19
19
|
const ALIAS = /^[a-z0-9][a-z0-9._-]{0,63}$/;
|
|
20
|
+
const ENTRY_KEYS: readonly string[] = ["alias", "model", "thinking", "compaction"];
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
22
|
+
const aliasOf = (value: unknown, index: number): ModelAlias => {
|
|
23
|
+
const location = `MODEL_ALIASES[${index}]`;
|
|
24
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
25
|
+
throw new Error(`${location} must be an object with alias, model, compaction and optionally thinking`);
|
|
26
|
+
}
|
|
27
|
+
const entry = value as Record<string, unknown>;
|
|
28
|
+
const unknown = Object.keys(entry).find((key) => !ENTRY_KEYS.includes(key));
|
|
29
|
+
if (unknown) throw new Error(`${location}.${unknown} is not supported; allowed are ${ENTRY_KEYS.join(", ")}`);
|
|
30
|
+
if (typeof entry.alias !== "string" || !ALIAS.test(entry.alias)) {
|
|
31
|
+
throw new Error(`${location}.alias needs 1 to 64 lowercase letters, digits, dots, underscores or hyphens`);
|
|
32
|
+
}
|
|
33
|
+
const target = typeof entry.model === "string" ? entry.model : "";
|
|
34
|
+
const slash = target.indexOf("/");
|
|
35
|
+
if (slash <= 0 || slash === target.length - 1) throw new Error(`${location}.model of ${entry.alias} needs the form "provider/model"`);
|
|
36
|
+
if (entry.thinking !== undefined && !isThinkingLevel(entry.thinking)) {
|
|
37
|
+
throw new Error(`${location}.thinking of ${entry.alias} names the unknown thinking level "${String(entry.thinking)}"`);
|
|
38
|
+
}
|
|
39
|
+
const problem = compactionProblem(entry.compaction);
|
|
40
|
+
if (problem) throw new Error(`${location}, ${entry.alias}: ${problem}`);
|
|
41
|
+
return {
|
|
42
|
+
alias: entry.alias,
|
|
43
|
+
upstream: target.slice(0, slash),
|
|
44
|
+
model: target.slice(slash + 1),
|
|
45
|
+
...(entry.thinking === undefined ? {} : { thinking: entry.thinking }),
|
|
46
|
+
compaction: entry.compaction as ModelAlias["compaction"],
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/** MODEL_ALIASES: eine Liste von { alias, model: "anbieter/modell", thinking?, compaction }; der Alias ist der einzige Name, den Oberfläche, Journal und Relay-Clients sehen. */
|
|
51
|
+
export const parseModelAliases = (entries: unknown): readonly ModelAlias[] => {
|
|
52
|
+
if (!Array.isArray(entries)) throw new Error("MODEL_ALIASES must be a list of aliases");
|
|
53
|
+
const aliases = entries.map(aliasOf);
|
|
37
54
|
const duplicate = aliases.find((entry, index) => aliases.findIndex((other) => other.alias === entry.alias) !== index);
|
|
38
|
-
if (duplicate) throw new Error(`MODEL_ALIASES
|
|
55
|
+
if (duplicate) throw new Error(`MODEL_ALIASES names the alias ${duplicate.alias} more than once`);
|
|
39
56
|
return aliases;
|
|
40
57
|
};
|
|
41
58
|
|
|
42
59
|
const env = declaredEnvironment(modelAliasEnvDescriptors);
|
|
43
60
|
|
|
44
|
-
|
|
61
|
+
/** Die Aliasse des Profils; in der Umgebung steht MODEL_ALIASES als JSON der Liste aus der Profildatei. */
|
|
62
|
+
export const configuredModelAliases = (): readonly ModelAlias[] => {
|
|
63
|
+
const value = env.optional("MODEL_ALIASES");
|
|
64
|
+
if (value === undefined || value === "") return [];
|
|
65
|
+
let parsed: unknown;
|
|
66
|
+
try {
|
|
67
|
+
parsed = JSON.parse(value);
|
|
68
|
+
} catch {
|
|
69
|
+
throw new Error("MODEL_ALIASES is no JSON list of aliases");
|
|
70
|
+
}
|
|
71
|
+
return parseModelAliases(parsed);
|
|
72
|
+
};
|
|
45
73
|
|
|
46
74
|
/** Der Katalog der Aliasse aus den eingebauten Katalogen ihrer Anbieter, so wie die Modelllaufzeit sie anbietet. */
|
|
47
75
|
export const aliasCatalog = (aliases: readonly ModelAlias[] = configuredModelAliases()): readonly Model<Api>[] => {
|
|
48
|
-
if (aliases.length === 0) throw new Error(`
|
|
76
|
+
if (aliases.length === 0) throw new Error(`The provider ${ALIAS_PROVIDER} needs MODEL_ALIASES in the host section`);
|
|
49
77
|
return aliases.map((entry) => {
|
|
50
78
|
const target = getBuiltinModels(entry.upstream as BuiltinProvider).find((model) => model.id === entry.model);
|
|
51
|
-
if (!target) throw new Error(`MODEL_ALIASES:
|
|
79
|
+
if (!target) throw new Error(`MODEL_ALIASES: the model ${entry.model} behind ${entry.alias} is missing from the catalog of ${entry.upstream}`);
|
|
52
80
|
const supported = getSupportedThinkingLevels(target);
|
|
53
81
|
if (entry.thinking !== undefined && !supported.includes(entry.thinking)) {
|
|
54
|
-
throw new Error(`MODEL_ALIASES:
|
|
82
|
+
throw new Error(`MODEL_ALIASES: the thinking level ${entry.thinking} does not exist for ${entry.alias} (valid: ${supported.join(", ")})`);
|
|
55
83
|
}
|
|
56
|
-
|
|
84
|
+
const problem = compactionProblem(entry.compaction, target);
|
|
85
|
+
if (problem) throw new Error(`MODEL_ALIASES: ${entry.alias} on ${entry.upstream}/${entry.model}: ${problem}`);
|
|
86
|
+
return aliasedModel(ALIAS_PROVIDER, entry, target);
|
|
57
87
|
});
|
|
58
88
|
};
|
|
59
89
|
|
|
60
|
-
/** Die Aliasse des Profils, geprüft gegen die Kataloge ihrer Ziele samt Denktiefe. */
|
|
90
|
+
/** Die Aliasse des Profils, geprüft gegen die Kataloge ihrer Ziele samt Denktiefe und Kompaktierungswerten. */
|
|
61
91
|
export const validatedModelAliases = (): readonly ModelAlias[] => {
|
|
62
92
|
const aliases = configuredModelAliases();
|
|
63
93
|
if (aliases.length > 0) aliasCatalog(aliases);
|
|
@@ -35,6 +35,8 @@ export interface ServerProcessSandboxOptions {
|
|
|
35
35
|
/** Die Adresse dieses Servers, etwa http://127.0.0.1:4710; ohne HTTP keine. */
|
|
36
36
|
readonly serverAddress: string | undefined;
|
|
37
37
|
readonly dataDirectory: string;
|
|
38
|
+
/** Wie der Betreiber die Sandbox abschaltet, so wie er es in die Profildatei schreibt; jede Meldung, die den Start verhindert, nennt es. */
|
|
39
|
+
readonly disableSetting: string;
|
|
38
40
|
readonly hostRoot?: string;
|
|
39
41
|
readonly platform?: NodeJS.Platform;
|
|
40
42
|
readonly environment?: NodeJS.ProcessEnv;
|
|
@@ -213,39 +215,38 @@ class SharedSandboxRuntime {
|
|
|
213
215
|
|
|
214
216
|
const sharedRuntime = new SharedSandboxRuntime();
|
|
215
217
|
|
|
216
|
-
const unsupported = (platform: NodeJS.Platform): Error => new Error(platform === "win32"
|
|
218
|
+
const unsupported = (platform: NodeJS.Platform, disableSetting: string): Error => new Error(platform === "win32"
|
|
217
219
|
? "Die Prozess-Sandbox gibt es auf einem Windows-Server nicht: dort lassen sich die Ordnerregeln je Run nicht setzen. "
|
|
218
|
-
+
|
|
219
|
-
+ "PROCESS_SANDBOX: \"off\" in der Sektion ragents.workspace."
|
|
220
|
+
+ `Wer den Server trotzdem unter Windows betreibt, schaltet sie in der Profildatei ausdrücklich ab: ${disableSetting}.`
|
|
220
221
|
: `Die Prozess-Sandbox kennt die Plattform ${platform} nicht; unterstützt sind macOS und Linux. `
|
|
221
|
-
+
|
|
222
|
+
+ `${disableSetting} schaltet sie ausdrücklich ab.`);
|
|
222
223
|
|
|
223
|
-
const missingDependencies = (errors: readonly string[]): Error => new Error(
|
|
224
|
+
const missingDependencies = (errors: readonly string[], disableSetting: string): Error => new Error(
|
|
224
225
|
`Die Prozess-Sandbox kann nicht starten: ${errors.join("; ")}. `
|
|
225
226
|
+ "Unter Linux braucht sie bubblewrap, socat und ripgrep (Debian/Ubuntu: apt-get install bubblewrap socat ripgrep). "
|
|
226
|
-
+
|
|
227
|
+
+ `${disableSetting} schaltet sie ausdrücklich ab.`);
|
|
227
228
|
|
|
228
|
-
const failedSelfTest = (detail: string): Error => new Error(
|
|
229
|
+
const failedSelfTest = (detail: string, disableSetting: string): Error => new Error(
|
|
229
230
|
`Die Prozess-Sandbox lässt sich auf diesem Rechner nicht starten: ${detail.trim() || "ohne Ausgabe"}. `
|
|
230
231
|
+ "Unter Linux braucht bubblewrap Benutzer-Namensräume; in einem Container muss das Profil des Containers sie erlauben. "
|
|
231
|
-
+
|
|
232
|
+
+ `${disableSetting} schaltet sie ausdrücklich ab.`);
|
|
232
233
|
|
|
233
|
-
const runSelfTest = (launch: ProcessLaunch, environment: NodeJS.ProcessEnv): Promise<void> => new Promise((resolve, reject) => {
|
|
234
|
+
const runSelfTest = (launch: ProcessLaunch, environment: NodeJS.ProcessEnv, disableSetting: string): Promise<void> => new Promise((resolve, reject) => {
|
|
234
235
|
const child = spawn(launch.command, [...launch.args], { stdio: ["ignore", "ignore", "pipe"], env: environment });
|
|
235
236
|
let stderr = "";
|
|
236
237
|
const timer = setTimeout(() => {
|
|
237
238
|
child.kill("SIGKILL");
|
|
238
|
-
reject(failedSelfTest(`keine Antwort nach ${SELF_TEST_TIMEOUT_MS / 1000} Sekunden
|
|
239
|
+
reject(failedSelfTest(`keine Antwort nach ${SELF_TEST_TIMEOUT_MS / 1000} Sekunden`, disableSetting));
|
|
239
240
|
}, SELF_TEST_TIMEOUT_MS);
|
|
240
241
|
child.stderr.on("data", (chunk: Buffer) => { stderr = (stderr + chunk.toString("utf8")).slice(-2_000); });
|
|
241
242
|
child.once("error", (error) => {
|
|
242
243
|
clearTimeout(timer);
|
|
243
|
-
reject(failedSelfTest(error.message));
|
|
244
|
+
reject(failedSelfTest(error.message, disableSetting));
|
|
244
245
|
});
|
|
245
246
|
child.once("close", (code) => {
|
|
246
247
|
clearTimeout(timer);
|
|
247
248
|
if (code === 0) resolve();
|
|
248
|
-
else reject(failedSelfTest(`Code ${code ?? "Signal"}: ${stderr}
|
|
249
|
+
else reject(failedSelfTest(`Code ${code ?? "Signal"}: ${stderr}`, disableSetting));
|
|
249
250
|
});
|
|
250
251
|
});
|
|
251
252
|
|
|
@@ -260,7 +261,7 @@ export class ServerProcessSandbox implements RunProcessSandboxes {
|
|
|
260
261
|
constructor(options: ServerProcessSandboxOptions) {
|
|
261
262
|
this.#options = options;
|
|
262
263
|
this.#platform = options.platform ?? process.platform;
|
|
263
|
-
if (this.#platform !== "darwin" && this.#platform !== "linux") throw unsupported(this.#platform);
|
|
264
|
+
if (this.#platform !== "darwin" && this.#platform !== "linux") throw unsupported(this.#platform, options.disableSetting);
|
|
264
265
|
this.#protected = protectedRoots(options, this.#platform);
|
|
265
266
|
this.#readable = [options.hostRoot ?? hostRoot(), ...toolchainDirectories(options, this.#protected)];
|
|
266
267
|
this.#searchPath = resolvedSearchPath(options.environment ?? process.env);
|
|
@@ -269,14 +270,14 @@ export class ServerProcessSandbox implements RunProcessSandboxes {
|
|
|
269
270
|
/** Prüft die Voraussetzungen, startet den Netz-Proxy und startet einmal einen Prozess in der Sandbox; jedes Scheitern ist ein Startfehler. */
|
|
270
271
|
async start(): Promise<void> {
|
|
271
272
|
const { errors } = SandboxManager.checkDependencies();
|
|
272
|
-
if (errors.length > 0) throw missingDependencies(errors);
|
|
273
|
+
if (errors.length > 0) throw missingDependencies(errors, this.#options.disableSetting);
|
|
273
274
|
await sharedRuntime.acquire(this, {
|
|
274
275
|
network: [...this.#options.network, ...serverTarget(this.#options.serverAddress)],
|
|
275
276
|
unixSockets: socketRoots(this.#options.dataDirectory, this.#platform),
|
|
276
277
|
});
|
|
277
278
|
try {
|
|
278
279
|
const probe = this.forRun({ writable: [], readable: [], temporary: path.join(this.#options.dataDirectory, "sandbox-self-test") });
|
|
279
|
-
await runSelfTest(await probe.wrap({ command: "true", args: [] }), this.#options.environment ?? process.env);
|
|
280
|
+
await runSelfTest(await probe.wrap({ command: "true", args: [] }), this.#options.environment ?? process.env, this.#options.disableSetting);
|
|
280
281
|
} catch (error) {
|
|
281
282
|
await sharedRuntime.release(this);
|
|
282
283
|
throw error;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { compactionProblem } from "@ragents/agent";
|
|
2
|
+
import type { Api, Model, ModelCompaction } from "@ragents/ai";
|
|
2
3
|
import type { ModelProviderRegistration } from "@ragents/engine";
|
|
3
4
|
|
|
4
5
|
export const RELAY_PROVIDER = "relay";
|
|
@@ -9,7 +10,7 @@ export interface RelayConnection {
|
|
|
9
10
|
readonly token: string;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
/** Was das Relay je Alias über das dahinterliegende Modell verrät; der echte Name bleibt beim Server. */
|
|
13
|
+
/** Was das Relay je Alias über das dahinterliegende Modell verrät, samt den Kompaktierungswerten des Alias; der echte Name bleibt beim Server. */
|
|
13
14
|
export interface RelayCatalogEntry {
|
|
14
15
|
readonly id: string;
|
|
15
16
|
readonly object: "model";
|
|
@@ -19,6 +20,7 @@ export interface RelayCatalogEntry {
|
|
|
19
20
|
readonly input: Model<Api>["input"];
|
|
20
21
|
readonly contextWindow: number;
|
|
21
22
|
readonly maxTokens: number;
|
|
23
|
+
readonly compaction: ModelCompaction;
|
|
22
24
|
readonly compat?: Model<Api>["compat"];
|
|
23
25
|
};
|
|
24
26
|
}
|
|
@@ -61,6 +63,7 @@ const modelOf = (entry: RelayCatalogEntry, baseUrl: string): Model<"openai-compl
|
|
|
61
63
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
62
64
|
contextWindow: entry.catalog.contextWindow,
|
|
63
65
|
maxTokens: entry.catalog.maxTokens,
|
|
66
|
+
compaction: entry.catalog.compaction,
|
|
64
67
|
...(entry.catalog.compat ? { compat: entry.catalog.compat as Model<"openai-completions">["compat"] } : {}),
|
|
65
68
|
});
|
|
66
69
|
|
|
@@ -83,6 +86,10 @@ export const createRelayCatalog = (connection: RelayConnection, fetchImpl: typeo
|
|
|
83
86
|
const body = await response.json() as { data?: unknown };
|
|
84
87
|
if (!Array.isArray(body.data) || !body.data.every(isEntry)) throw new Error(`Das Modell-Relay ${address} liefert keinen gültigen Aliaskatalog`);
|
|
85
88
|
if (body.data.length === 0) throw new Error(`Das Modell-Relay ${address} bietet keine Modelle an`);
|
|
89
|
+
for (const entry of body.data) {
|
|
90
|
+
const problem = compactionProblem(entry.catalog.compaction, entry.catalog);
|
|
91
|
+
if (problem) throw new Error(`The model relay ${address} offers ${entry.id} without valid compaction values: ${problem}`);
|
|
92
|
+
}
|
|
86
93
|
loaded = body.data.map((entry) => modelOf(entry, baseUrl));
|
|
87
94
|
return loaded;
|
|
88
95
|
};
|
|
@@ -110,6 +117,7 @@ export const createRelayCatalog = (connection: RelayConnection, fetchImpl: typeo
|
|
|
110
117
|
cost: model.cost,
|
|
111
118
|
contextWindow: model.contextWindow,
|
|
112
119
|
maxTokens: model.maxTokens,
|
|
120
|
+
...(model.compaction ? { compaction: model.compaction } : {}),
|
|
113
121
|
...(model.compat ? { compat: model.compat } : {}),
|
|
114
122
|
})),
|
|
115
123
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdir, realpath } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { Value } from "typebox/value";
|
|
3
4
|
import {
|
|
4
5
|
DomainError,
|
|
5
6
|
serviceToken,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
type SessionIdent,
|
|
29
30
|
type WorkspaceExecuteOptions,
|
|
30
31
|
type WorkspaceExecutor,
|
|
32
|
+
type WorkspaceExecutorParts,
|
|
31
33
|
type WorkspaceProcessContext,
|
|
32
34
|
} from "@ragents/workspace-executor";
|
|
33
35
|
import { hostRoot } from "../host-version.js";
|
|
@@ -70,6 +72,8 @@ export const sandboxServicesToken = serviceToken<SandboxServices>("ragents.works
|
|
|
70
72
|
|
|
71
73
|
export interface WorkspaceSandboxHostOptions {
|
|
72
74
|
contributorName: string;
|
|
75
|
+
/** Was die Plugins des Profils zum Executor dieses Servers beitragen; jeder Arbeitsplatz der Runs trägt dieselben Beiträge. */
|
|
76
|
+
contributions: readonly WorkspaceExecutorParts[];
|
|
73
77
|
workspaceFor: (runId: string) => Promise<SessionWorkspace>;
|
|
74
78
|
identFor: (runId: string) => Promise<SessionIdent | undefined>;
|
|
75
79
|
skillPaths: () => Promise<readonly string[]>;
|
|
@@ -83,6 +87,10 @@ export interface WorkspaceSandboxHostOptions {
|
|
|
83
87
|
processSandbox?: RunProcessSandboxes;
|
|
84
88
|
/** Die Bash des Executors dieses Servers; unter Windows Pflicht, sonst ohne Angabe die des Systems. */
|
|
85
89
|
bash?: string;
|
|
90
|
+
/** Das rg des Executors dieses Servers; ohne Angabe gilt eines im PATH. */
|
|
91
|
+
rg?: string;
|
|
92
|
+
/** Die Zeitgrenze von bash in Sekunden für Aufrufe ohne eigene, auf jeder Maschine der Runs; ohne Angabe die des Werkzeugs. */
|
|
93
|
+
bashTimeoutSeconds?: number;
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
const sandboxDescriptions: Readonly<Record<string, string>> = {
|
|
@@ -98,16 +106,13 @@ const describeSandboxTool = (definition: AgentToolDefinition): AgentToolDefiniti
|
|
|
98
106
|
return { ...definition, description, longDescription: definition.description, nativeTool: true };
|
|
99
107
|
};
|
|
100
108
|
|
|
101
|
-
const
|
|
109
|
+
const sandboxDefinitions = (bashTimeoutSeconds: number | undefined): readonly AgentToolDefinition[] => [
|
|
102
110
|
createReadToolDefinition("."),
|
|
103
111
|
createEditToolDefinition("."),
|
|
104
112
|
createWriteToolDefinition("."),
|
|
105
|
-
createBashToolDefinition("."),
|
|
113
|
+
createBashToolDefinition(".", bashTimeoutSeconds === undefined ? {} : { defaultTimeoutSeconds: bashTimeoutSeconds }),
|
|
106
114
|
] as readonly AgentToolDefinition[];
|
|
107
115
|
|
|
108
|
-
const sandboxDescriptors = sandboxDescriptorDefinitions.map((definition) =>
|
|
109
|
-
toolDescriptorFrom(describeSandboxTool(definition), alwaysAvailable));
|
|
110
|
-
|
|
111
116
|
const fileToolNames = new Set(["read", "edit", "write"]);
|
|
112
117
|
|
|
113
118
|
interface StableRunParts {
|
|
@@ -142,6 +147,7 @@ const existingRoots = async (roots: readonly ResolvedWorkspaceRoot[]): Promise<R
|
|
|
142
147
|
/** Der Executor des Servers mit den Wurzeln des Servers; eine Operation mit Alias läuft dort, jede andere beim Executor der Bindung des Runs. */
|
|
143
148
|
export class WorkspaceSandboxHost implements SandboxServices {
|
|
144
149
|
readonly #options: WorkspaceSandboxHostOptions;
|
|
150
|
+
readonly #definitions: readonly AgentToolDefinition[];
|
|
145
151
|
readonly #workspaceRoots: RegisteredWorkspaceRoot[] = [];
|
|
146
152
|
readonly #local: WorkspaceOperationExecutor;
|
|
147
153
|
readonly #stable = new Map<string, Promise<StableRunParts>>();
|
|
@@ -150,9 +156,10 @@ export class WorkspaceSandboxHost implements SandboxServices {
|
|
|
150
156
|
|
|
151
157
|
constructor(options: WorkspaceSandboxHostOptions) {
|
|
152
158
|
this.#options = options;
|
|
159
|
+
this.#definitions = sandboxDefinitions(options.bashTimeoutSeconds);
|
|
153
160
|
this.#local = new WorkspaceOperationExecutor({
|
|
154
161
|
contextFor: (runId) => this.serverProcessContextFor(runId),
|
|
155
|
-
modules: workspaceExecutorModules(),
|
|
162
|
+
modules: workspaceExecutorModules({ contributions: options.contributions }),
|
|
156
163
|
});
|
|
157
164
|
}
|
|
158
165
|
|
|
@@ -234,6 +241,7 @@ export class WorkspaceSandboxHost implements SandboxServices {
|
|
|
234
241
|
runOperation: workspace.runOperation,
|
|
235
242
|
...(sandbox ? { sandbox } : {}),
|
|
236
243
|
...(this.#options.bash === undefined ? {} : { bash: this.#options.bash }),
|
|
244
|
+
...(this.#options.rg === undefined ? {} : { rg: this.#options.rg }),
|
|
237
245
|
});
|
|
238
246
|
}
|
|
239
247
|
|
|
@@ -288,7 +296,7 @@ export class WorkspaceSandboxHost implements SandboxServices {
|
|
|
288
296
|
workspaceTools(): ToolContributor {
|
|
289
297
|
return {
|
|
290
298
|
name: this.#options.contributorName,
|
|
291
|
-
descriptors:
|
|
299
|
+
descriptors: this.#definitions.map((definition) => toolDescriptorFrom(describeSandboxTool(definition), alwaysAvailable)),
|
|
292
300
|
tools: (context) => this.#workspaceToolsFor(context),
|
|
293
301
|
};
|
|
294
302
|
}
|
|
@@ -330,12 +338,13 @@ export class WorkspaceSandboxHost implements SandboxServices {
|
|
|
330
338
|
}
|
|
331
339
|
|
|
332
340
|
#workspaceToolsFor(context: PluginContext): Promise<RunFunction[]> {
|
|
333
|
-
return Promise.resolve(
|
|
341
|
+
return Promise.resolve(this.#definitions.map((definition) => {
|
|
334
342
|
const described = describeSandboxTool(definition);
|
|
335
343
|
const proxy = {
|
|
336
344
|
...described,
|
|
345
|
+
// Die Vorgaben des Schemas, etwa die Zeitgrenze von bash, setzt der Server ein; so gilt auf jeder Maschine, was das Modell im Schema sieht.
|
|
337
346
|
execute: (toolCallId: string, params: unknown, signal: AbortSignal | undefined) =>
|
|
338
|
-
this.execute(context.runId, described.name, params, {
|
|
347
|
+
this.execute(context.runId, described.name, Value.Default(described.parameters, structuredClone(params)), {
|
|
339
348
|
toolCallId,
|
|
340
349
|
...(signal ? { signal } : {}),
|
|
341
350
|
}),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { EXECUTOR_CONTRIBUTION_FILE } from "@ragents/workspace-executor";
|
|
4
5
|
import { ragentsDataRoot } from "../data-directory.js";
|
|
5
6
|
import { filesBelow } from "../folder-install.js";
|
|
6
7
|
import { HOST_API_VERSION, type HostApiHalf } from "../host-api.js";
|
|
@@ -9,7 +10,7 @@ import { isCheckout } from "../host-web.js";
|
|
|
9
10
|
import { bundlesRoot, pluginIdOf } from "../plugin-support/plugins-root.js";
|
|
10
11
|
|
|
11
12
|
export const BUNDLE_MANIFEST_FILE = "ragents-bundle.json";
|
|
12
|
-
export const BUNDLE_FORMAT =
|
|
13
|
+
export const BUNDLE_FORMAT = 4;
|
|
13
14
|
|
|
14
15
|
/** The value names a half imports from each module of the host API. */
|
|
15
16
|
export type HostNames = Readonly<Record<string, readonly string[]>>;
|
|
@@ -27,12 +28,14 @@ export interface BundleManifest {
|
|
|
27
28
|
readonly sourceStand: string;
|
|
28
29
|
readonly server: string;
|
|
29
30
|
readonly web?: { readonly entry: string; readonly css?: string; readonly classes: string };
|
|
31
|
+
/** The contribution to every executor, a self-contained file that any Node process loads. */
|
|
32
|
+
readonly executor?: typeof EXECUTOR_CONTRIBUTION_FILE;
|
|
30
33
|
readonly exports: Readonly<Record<HostApiHalf, Readonly<Record<string, string>>>>;
|
|
31
34
|
readonly uses: readonly string[];
|
|
32
35
|
readonly assets: readonly string[];
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
const MANIFEST_KEYS = new Set(["format", "id", "api", "hostNames", "stand", "sourceStand", "server", "web", "exports", "uses", "assets"]);
|
|
38
|
+
const MANIFEST_KEYS = new Set(["format", "id", "api", "hostNames", "stand", "sourceStand", "server", "web", "executor", "exports", "uses", "assets"]);
|
|
36
39
|
const SOURCE_MARKERS = ["ragents-plugin.json", "server/index.ts", "server/index.tsx"];
|
|
37
40
|
|
|
38
41
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
@@ -167,6 +170,7 @@ export const readBundleManifest = (folder: string): BundleManifest => {
|
|
|
167
170
|
...(typeof raw.sourceStand === "string" ? [] : ["sourceStand"]),
|
|
168
171
|
...(typeof raw.server === "string" ? [] : ["server"]),
|
|
169
172
|
...(isWeb(raw.web) ? [] : ["web"]),
|
|
173
|
+
...(raw.executor === undefined || raw.executor === EXECUTOR_CONTRIBUTION_FILE ? [] : ["executor"]),
|
|
170
174
|
...(isRecord(raw.exports) && isPathRecord(raw.exports.server) && isPathRecord(raw.exports.web) ? [] : ["exports"]),
|
|
171
175
|
...(isStringList(raw.uses) ? [] : ["uses"]),
|
|
172
176
|
...(isStringList(raw.assets) ? [] : ["assets"]),
|
|
@@ -176,7 +180,7 @@ export const readBundleManifest = (folder: string): BundleManifest => {
|
|
|
176
180
|
const webFiles = web === undefined ? [] : [web.entry, web.classes, ...(web.css === undefined ? [] : [web.css])];
|
|
177
181
|
const misplaced = webFiles.filter((entry) => !entry.startsWith("web/") || entry.split("/").includes(".."));
|
|
178
182
|
if (misplaced.length > 0) throw new Error(`${file}: ${misplaced.join(", ")} liegt nicht unter web/; ${rebuildHint(folder)}`);
|
|
179
|
-
for (const required of [raw.server as string, ...webFiles]) {
|
|
183
|
+
for (const required of [raw.server as string, ...webFiles, ...(raw.executor === undefined ? [] : [EXECUTOR_CONTRIBUTION_FILE])]) {
|
|
180
184
|
if (!statSync(path.join(folder, required), { throwIfNoEntry: false })?.isFile()) throw new Error(`Dem Bundle ${id} fehlt ${required}; ${rebuildHint(folder)}`);
|
|
181
185
|
}
|
|
182
186
|
return raw as unknown as BundleManifest;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PluginHost, type PluginWebAddresses } from "@ragents/engine";
|
|
2
|
+
import { pluginToolsDirectory, prepareExecutorContribution, type LoadedExecutorContribution } from "@ragents/workspace-executor";
|
|
2
3
|
import { config, HOST_SECRET_ENV_NAMES } from "../config.js";
|
|
3
4
|
import { SESSION_MODE, SESSIONS_MODE } from "../layout.js";
|
|
4
5
|
import { withFolderAssets } from "../plugin-support/plugin-folder.js";
|
|
@@ -6,6 +7,7 @@ import type { PluginModule } from "../plugin-support/plugin-module.js";
|
|
|
6
7
|
import { runManagementToken } from "../ragents/global-chat.js";
|
|
7
8
|
import { registerTypeScriptFunctions } from "../ragents/typescript-tools.js";
|
|
8
9
|
import {
|
|
10
|
+
executorContributionsToken,
|
|
9
11
|
hostAddressToken,
|
|
10
12
|
runtimeProviderToken,
|
|
11
13
|
secretEnvNamesToken,
|
|
@@ -27,6 +29,8 @@ export interface ProfileComposition {
|
|
|
27
29
|
readonly modules: ReadonlyMap<string, PluginModule>;
|
|
28
30
|
/** The plugins with a web half and where the browser loads it; the web loads exactly these. */
|
|
29
31
|
readonly web: ReadonlyMap<string, PluginWebAddresses>;
|
|
32
|
+
/** Die Beiträge der Bundles zum Executor; der Server baut sie mit den Werkzeugordnern seines Datenordners. */
|
|
33
|
+
readonly executor: readonly LoadedExecutorContribution[];
|
|
30
34
|
/** Die Vorlage aus defaultStartEntry der Profildatei; der Host lehnt eine nicht registrierte beim Versiegeln ab. */
|
|
31
35
|
readonly defaultStartEntry?: string;
|
|
32
36
|
}
|
|
@@ -43,6 +47,8 @@ export const composeProfile = (options: ProfileComposition, bridges: HostBridges
|
|
|
43
47
|
host.provideHost(runWorkspaceProviderToken, bridges.sessionWorkspaceFor);
|
|
44
48
|
host.provideHost(runtimeProviderToken, bridges.runtime);
|
|
45
49
|
host.provideHost(hostAddressToken, () => bridges.apiBaseUrl);
|
|
50
|
+
host.provideHost(executorContributionsToken, options.executor.map((loaded) =>
|
|
51
|
+
prepareExecutorContribution(loaded, pluginToolsDirectory(config.dataDir, loaded.plugin))));
|
|
46
52
|
host.provideHost(runManagementToken, () => {
|
|
47
53
|
if (!bridges.sessions) throw new Error("Der Host stellt keine Sitzungsverwaltung bereit");
|
|
48
54
|
return bridges.sessions();
|
|
@@ -2,6 +2,7 @@ import { existsSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import type { PluginWebAddresses } from "@ragents/engine";
|
|
5
|
+
import { loadExecutorContribution, type LoadedExecutorContribution } from "@ragents/workspace-executor";
|
|
5
6
|
import { announceBundles } from "../host-resolution.js";
|
|
6
7
|
import { checkedHostApiRecord } from "../host-version.js";
|
|
7
8
|
import { isPluginModule, type PluginModule } from "../plugin-support/plugin-module.js";
|
|
@@ -133,6 +134,8 @@ export interface LoadedPlugins {
|
|
|
133
134
|
readonly bundles: readonly ResolvedPlugin[];
|
|
134
135
|
/** The plugins whose bundle carries a web half, with the addresses the browser loads it from. */
|
|
135
136
|
readonly web: ReadonlyMap<string, PluginWebAddresses>;
|
|
137
|
+
/** The contributions to every executor, in the order of the plugin list; each machine builds them for itself. */
|
|
138
|
+
readonly executor: readonly LoadedExecutorContribution[];
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
export const loadPlugins = async (
|
|
@@ -160,5 +163,7 @@ export const loadPlugins = async (
|
|
|
160
163
|
const addresses = webAddressesOf(plugin);
|
|
161
164
|
return addresses === undefined ? [] : [[plugin.id, addresses] as const];
|
|
162
165
|
}));
|
|
163
|
-
|
|
166
|
+
const executor = await Promise.all(plugins.flatMap((plugin) => plugin.manifest.executor === undefined ? []
|
|
167
|
+
: [loadExecutorContribution(plugin.id, path.join(plugin.folder, plugin.manifest.executor))]));
|
|
168
|
+
return { known, ids, modules, bundles: plugins, web, executor };
|
|
164
169
|
};
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { mkdir } from "node:fs/promises";
|
|
2
2
|
import { hostDataDirectory, pluginToolsDirectory } from "@ragents/workspace-executor/src/tools.ts";
|
|
3
3
|
import { isPluginProvision, type PluginProvision } from "../plugin-support/provision.js";
|
|
4
|
-
import { importBundles, resolvePluginEntries, type ResolvedPlugin } from "./plugin-discovery.js";
|
|
5
|
-
|
|
6
|
-
/** Die Plugins, deren Werkzeuge jeder Arbeitsplatz-Executor auf seiner Maschine braucht: Sprachserver und Browser. */
|
|
7
|
-
export const WORKSPACE_PROVISION_PLUGINS = ["ragents.lsp-roslyn", "ragents.lsp-fsharp", "ragents.browser"] as const;
|
|
4
|
+
import { discoverPluginIds, importBundles, resolvePluginEntries, type ResolvedPlugin } from "./plugin-discovery.js";
|
|
8
5
|
|
|
9
6
|
/** The provisioning a bundle exports next to its plugin, if it brings one. */
|
|
10
7
|
const provisionOf = (plugin: ResolvedPlugin, exported: Readonly<Record<string, unknown>>): PluginProvision | undefined => {
|
|
@@ -81,5 +78,9 @@ const withUsedBundles = (ids: readonly string[]): readonly ResolvedPlugin[] => {
|
|
|
81
78
|
return [...resolved.values()];
|
|
82
79
|
};
|
|
83
80
|
|
|
81
|
+
/** Ein Arbeitsplatz hat kein Profil; er provisioniert die eingebauten Plugins seines Hosts, die zum Executor beitragen, denn deren Werkzeuge laufen auf ihm. */
|
|
82
|
+
export const workspaceProvisionPlugins = (): readonly ResolvedPlugin[] => withUsedBundles(
|
|
83
|
+
resolvePluginEntries(discoverPluginIds()).filter((plugin) => plugin.manifest.executor !== undefined).map((plugin) => plugin.id));
|
|
84
|
+
|
|
84
85
|
export const provisionWorkspace = (log: (line: string) => void): Promise<readonly PluginProvisionReport[]> =>
|
|
85
|
-
provisionPlugins(
|
|
86
|
+
provisionPlugins(workspaceProvisionPlugins(), hostDataDirectory(), log);
|
|
@@ -366,7 +366,7 @@ export class RunSessionProvider implements ChatSessionProvider {
|
|
|
366
366
|
else if (start.kind === "package") {
|
|
367
367
|
if (!local) throw new Error("Das Run-Script-Paket wurde nicht geladen");
|
|
368
368
|
const { script, ...entry } = local;
|
|
369
|
-
await session.startPackageAndWait({ ...script, entry: { ...entry, coordinator: script.coordinator, owner:
|
|
369
|
+
await session.startPackageAndWait({ ...script, entry: { ...entry, coordinator: script.coordinator, owner: start.owner } }, start.input, user);
|
|
370
370
|
}
|
|
371
371
|
else await session.sendAndWait(start.message, user);
|
|
372
372
|
return id;
|
|
@@ -398,7 +398,7 @@ export class RunSessionProvider implements ChatSessionProvider {
|
|
|
398
398
|
|
|
399
399
|
runView(id: string, access: AccessContext = unrestrictedAccess): unknown {
|
|
400
400
|
this.ensureUsable(id);
|
|
401
|
-
return accessibleRunView(this.requireEngine().runtime.view(id), access);
|
|
401
|
+
return accessibleRunView(this.requireEngine().runtime.view(id), access, this.plugins.accessProjections);
|
|
402
402
|
}
|
|
403
403
|
|
|
404
404
|
hasRun(id: string): boolean {
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
type PublicPromptSnapshot,
|
|
33
33
|
type RunStopBoundary,
|
|
34
34
|
type RunStopOperation,
|
|
35
|
+
type RunView,
|
|
35
36
|
type StartOptionContributionRegistry,
|
|
36
37
|
type Workspaces,
|
|
37
38
|
} from "@ragents/engine";
|
|
@@ -206,7 +207,6 @@ export const createEngine = async (options: EngineOptions): Promise<Engine> => {
|
|
|
206
207
|
resolveSkills: async (context) => globalChat?.isCoordinator(context.runId) ? []
|
|
207
208
|
: (await options.plugins.skills.resolve(contributionContextFor(context))).map(skillOfDirectory),
|
|
208
209
|
resolveHooks: (context) => globalChat?.isCoordinator(context.runId) ? [] : options.plugins.agentRuntime.resolve(contributionContextFor(context)),
|
|
209
|
-
settings: { compaction: config.agentCompaction },
|
|
210
210
|
});
|
|
211
211
|
const configuredModels = await Promise.all(options.plugins.profiles.models().map(async (model) => {
|
|
212
212
|
if (model.driver !== "agent") return model;
|
|
@@ -398,7 +398,7 @@ export const createEngine = async (options: EngineOptions): Promise<Engine> => {
|
|
|
398
398
|
assertAvailable: options.assertAvailable,
|
|
399
399
|
assertRunUsable: options.assertRunUsable,
|
|
400
400
|
assertRunRights: (access: AccessContext, runId: string, kind: RunRightsKind) => assertRunRights(access, runId, kind, runAccess),
|
|
401
|
-
projectView: accessibleRunView,
|
|
401
|
+
projectView: (view: RunView, access: AccessContext) => accessibleRunView(view, access, options.plugins.accessProjections),
|
|
402
402
|
hasRun: (runId: string) => journal.stateOf(runId) !== null,
|
|
403
403
|
};
|
|
404
404
|
const methods = runtimeMethods({
|
|
@@ -31,7 +31,13 @@ export type ManagedRunStart = {
|
|
|
31
31
|
/** Wer die Startoptionen wählt und den Run besitzt: der Benutzer der Anfrage, null ohne Anmeldung. */
|
|
32
32
|
user: ChatUser | null;
|
|
33
33
|
} & ({ kind: "message"; message: string } | { kind: "script"; entryId: string; input: JsonValue }
|
|
34
|
-
| {
|
|
34
|
+
| {
|
|
35
|
+
kind: "package";
|
|
36
|
+
directory: string;
|
|
37
|
+
input: JsonValue;
|
|
38
|
+
/** Das Plugin, das das Paket startet; es steht als Besitzer der Vorlage dieses Starts. */
|
|
39
|
+
owner: string;
|
|
40
|
+
});
|
|
35
41
|
|
|
36
42
|
export interface RunManagement {
|
|
37
43
|
/** Mit einem Zugang bleiben nur dessen eigene Runs übrig; ohne ihn ist es die Liste des Servers. */
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
type PluginHost,
|
|
6
6
|
type ServiceToken,
|
|
7
7
|
} from "@ragents/engine";
|
|
8
|
+
import type { PreparedExecutorContribution } from "@ragents/workspace-executor";
|
|
8
9
|
import type { SessionWorkspace } from "./workspace-runtime.js";
|
|
9
10
|
import type { RunManagement } from "./global-chat.js";
|
|
10
11
|
|
|
@@ -23,6 +24,9 @@ export const runtimeProviderToken: ServiceToken<() => Orchestration> = serviceTo
|
|
|
23
24
|
/** Die Adresse, unter der dieser Server seine API anbietet, etwa http://127.0.0.1:4710; ohne HTTP (nur stdio) keine. */
|
|
24
25
|
export const hostAddressToken: ServiceToken<() => string | undefined> = serviceToken("host.address");
|
|
25
26
|
|
|
27
|
+
/** Die Beiträge der Bundles dieses Profils zum Executor, gebaut für den Server; jeder Executor des Servers trägt sie, jeder Arbeitsplatz dieselben. */
|
|
28
|
+
export const executorContributionsToken: ServiceToken<readonly PreparedExecutorContribution[]> = serviceToken("host.executor-contributions");
|
|
29
|
+
|
|
26
30
|
export interface HostBridges {
|
|
27
31
|
ensureSession: (runId: string) => void;
|
|
28
32
|
ensureWorkspaceAccess: (access: AccessContext, runId: string) => void;
|
|
@@ -464,7 +464,7 @@ export class RunChatSession implements ChatSessionLike {
|
|
|
464
464
|
this.#engine.runtime.enqueueInput(
|
|
465
465
|
{ actorId: state.ownerId, commandId: `chat:${randomUUID()}` },
|
|
466
466
|
this.id,
|
|
467
|
-
{ actorId: primaryActorId, content: text, artifactIds, sourceEventIds },
|
|
467
|
+
{ actorId: primaryActorId, content: text, artifactIds, sourceEventIds, origin: "human" },
|
|
468
468
|
);
|
|
469
469
|
}
|
|
470
470
|
|
|
@@ -23,7 +23,7 @@ import { Protocol, teeConsole } from "./protocol.js";
|
|
|
23
23
|
import { RunSessionProvider } from "./provider.js";
|
|
24
24
|
import { readHelpResponse } from "./help-files.js";
|
|
25
25
|
import { watchParentProcess } from "./parent-watch.js";
|
|
26
|
-
import { hostRoot } from "./host-version.js";
|
|
26
|
+
import { hostRoot, readPackageVersion } from "./host-version.js";
|
|
27
27
|
import { hostWebProblem, isCheckout } from "./host-web.js";
|
|
28
28
|
import { createStylesheet, STYLESHEET_PATH } from "./web-stylesheet.js";
|
|
29
29
|
import { isBundleSourceMap, isPublicBundleFile, isWebBundlePath, webBundleFile } from "./web-bundles.js";
|
|
@@ -170,6 +170,7 @@ const composition: ProfileComposition = {
|
|
|
170
170
|
pluginIds: loaded.ids,
|
|
171
171
|
modules: loaded.modules,
|
|
172
172
|
web: loaded.web,
|
|
173
|
+
executor: loaded.executor,
|
|
173
174
|
...(defaultStartEntry !== undefined ? { defaultStartEntry } : {}),
|
|
174
175
|
};
|
|
175
176
|
|
|
@@ -213,6 +214,7 @@ provider.plugins.methods.register("host", [
|
|
|
213
214
|
...coreMethods({
|
|
214
215
|
sessions: provider,
|
|
215
216
|
plugins: provider.plugins,
|
|
217
|
+
version: readPackageVersion(),
|
|
216
218
|
global: globalAccess,
|
|
217
219
|
runOwner: (runId) => provider.runOwner(runId),
|
|
218
220
|
runOwnerOnly: (runId) => provider.runOwnerOnly(runId),
|
|
@@ -222,6 +224,7 @@ provider.plugins.methods.register("host", [
|
|
|
222
224
|
]);
|
|
223
225
|
provider.plugins.channels.register("host", coreChannels({
|
|
224
226
|
sessions: provider,
|
|
227
|
+
plugins: provider.plugins,
|
|
225
228
|
global: globalAccess,
|
|
226
229
|
runOwner: (runId) => provider.runOwner(runId),
|
|
227
230
|
runOwnerOnly: (runId) => provider.runOwnerOnly(runId),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,S as d,E as p,j as E,c as f}from"./mermaid-HWGCJPDP-
|
|
1
|
+
import{r,S as d,E as p,j as E,c as f}from"./mermaid-HWGCJPDP-BLLeth5_.js";var j=({code:i,language:e,maxHeight:o,raw:a,className:u,startLine:m,lineNumbers:n,...h})=>{let{shikiTheme:l}=r.useContext(d),t=p(),[c,s]=r.useState(a);return r.useEffect(()=>{if(!t){s(a);return}let g=t.highlight({code:i,language:e,themes:l},x=>{s(x)});g&&s(g)},[i,e,l,t,a]),E.jsx(f,{className:u,language:e,lineNumbers:n,maxHeight:o,result:c,startLine:m,...h})};export{j as HighlightedCodeBlockBody};
|