@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.
Files changed (218) hide show
  1. package/apps/server/package.json +1 -1
  2. package/apps/server/src/access-projection.ts +6 -36
  3. package/apps/server/src/api/contracts.ts +5 -2
  4. package/apps/server/src/api/core-methods.ts +5 -3
  5. package/apps/server/src/config-definition.ts +24 -2
  6. package/apps/server/src/config-file.ts +1 -1
  7. package/apps/server/src/config.ts +0 -6
  8. package/apps/server/src/host-api.json +5 -10
  9. package/apps/server/src/host-api.ts +6 -7
  10. package/apps/server/src/plugin-build/build.ts +28 -5
  11. package/apps/server/src/plugin-build/plugin-description.ts +1 -1
  12. package/apps/server/src/plugin-build/typecheck.ts +2 -2
  13. package/apps/server/src/plugin-support/language-server/plugin.ts +8 -7
  14. package/apps/server/src/plugin-support/language-server/tools.ts +7 -6
  15. package/apps/server/src/plugin-support/model-aliases.ts +55 -25
  16. package/apps/server/src/plugin-support/process-sandbox.ts +16 -15
  17. package/apps/server/src/plugin-support/product-relay.ts +10 -2
  18. package/apps/server/src/plugin-support/workspace-sandbox-host.ts +18 -9
  19. package/apps/server/src/profile/bundle-manifest.ts +7 -3
  20. package/apps/server/src/profile/compose.ts +6 -0
  21. package/apps/server/src/profile/plugin-discovery.ts +6 -1
  22. package/apps/server/src/profile/provisioning.ts +6 -5
  23. package/apps/server/src/provider.ts +2 -2
  24. package/apps/server/src/ragents/engine.ts +2 -2
  25. package/apps/server/src/ragents/global-chat.ts +7 -1
  26. package/apps/server/src/ragents/host-services.ts +4 -0
  27. package/apps/server/src/ragents/session.ts +1 -1
  28. package/apps/server/src/server.ts +4 -1
  29. package/apps/server/tsconfig.json +2 -0
  30. package/apps/web/dist/assets/{highlighted-body-KPVGNVTW-xXXhTDbh.js → highlighted-body-KPVGNVTW-BO4wLQtE.js} +1 -1
  31. package/apps/web/dist/assets/main-DnnqWHkH.js +11 -0
  32. package/apps/web/dist/assets/mermaid-HWGCJPDP-BLLeth5_.js +568 -0
  33. package/apps/web/dist/assets/{runPanel-ZT6TPDLM.js → runPanel-DPm7s3KM.js} +2 -2
  34. package/apps/web/dist/help/guide-clients.html +26 -8
  35. package/apps/web/dist/help/guide-clients.md +27 -8
  36. package/apps/web/dist/help/guide-distributed.html +12 -4
  37. package/apps/web/dist/help/guide-distributed.md +12 -4
  38. package/apps/web/dist/help/guide-getting-started.html +12 -8
  39. package/apps/web/dist/help/guide-getting-started.md +12 -8
  40. package/apps/web/dist/help/guide-plugins.html +6 -2
  41. package/apps/web/dist/help/guide-plugins.md +6 -2
  42. package/apps/web/dist/help/guide-runtime.html +2 -1
  43. package/apps/web/dist/help/guide-runtime.md +2 -1
  44. package/apps/web/dist/help/index.html +4328 -1132
  45. package/apps/web/dist/help/mini-app.css +24 -0
  46. package/apps/web/dist/host-web.json +4 -4
  47. package/apps/web/dist/index.html +2 -2
  48. package/apps/web/dist/run-panel.html +2 -2
  49. package/apps/web/package.json +1 -1
  50. package/apps/web/src/panel/ConnectionsPage.tsx +3 -0
  51. package/apps/web/src/panel/StartPage.tsx +3 -0
  52. package/apps/web/src/panel/contract.ts +7 -0
  53. package/bundles/ragents.activity/ragents-bundle.json +3 -3
  54. package/bundles/ragents.actor-programs/ragents-bundle.json +4 -4
  55. package/bundles/ragents.actor-programs/server/index.js +31 -3
  56. package/bundles/ragents.actor-programs/server/index.js.map +4 -4
  57. package/bundles/ragents.actor-programs/web/index.js.map +1 -1
  58. package/bundles/ragents.ask/ragents-bundle.json +4 -6
  59. package/bundles/ragents.ask/server/index.js +42 -11
  60. package/bundles/ragents.ask/server/index.js.map +3 -3
  61. package/bundles/ragents.ask/web/chunks/{chunk-V7W3QDVS.js → chunk-MBRPS477.js} +2 -2
  62. package/bundles/ragents.ask/web/chunks/{chunk-V7W3QDVS.js.map → chunk-MBRPS477.js.map} +4 -4
  63. package/bundles/ragents.ask/web/chunks/chunk-WFN4374U.js +2 -0
  64. package/bundles/ragents.ask/web/chunks/chunk-WFN4374U.js.map +7 -0
  65. package/bundles/ragents.ask/web/classes.json +1 -1
  66. package/bundles/ragents.ask/web/exports/ask-payload.js +1 -1
  67. package/bundles/ragents.ask/web/exports/web/QuestionCard.js +1 -1
  68. package/bundles/ragents.ask/web/index.js +1 -1
  69. package/bundles/ragents.ask/web/index.js.map +4 -4
  70. package/bundles/ragents.browser/executor/index.mjs +357 -0
  71. package/bundles/ragents.browser/executor/index.mjs.map +7 -0
  72. package/bundles/ragents.browser/ragents-bundle.json +5 -8
  73. package/bundles/ragents.browser/server/chunks/{chunk-2GKLLCBE.js → chunk-CWLX4VA5.js} +1 -1
  74. package/bundles/ragents.browser/server/chunks/chunk-CWLX4VA5.js.map +7 -0
  75. package/bundles/ragents.browser/server/exports/server/contract.js +1 -1
  76. package/bundles/ragents.browser/server/index.js +20 -9
  77. package/bundles/ragents.browser/server/index.js.map +4 -4
  78. package/bundles/ragents.documents/ragents-bundle.json +3 -3
  79. package/bundles/ragents.lsp-fsharp/executor/index.mjs +68 -0
  80. package/bundles/ragents.lsp-fsharp/executor/index.mjs.map +7 -0
  81. package/bundles/ragents.lsp-fsharp/ragents-bundle.json +5 -9
  82. package/bundles/ragents.lsp-fsharp/server/index.js +21 -6
  83. package/bundles/ragents.lsp-fsharp/server/index.js.map +4 -4
  84. package/bundles/ragents.lsp-roslyn/executor/index.mjs +68 -0
  85. package/bundles/ragents.lsp-roslyn/executor/index.mjs.map +7 -0
  86. package/bundles/ragents.lsp-roslyn/ragents-bundle.json +6 -8
  87. package/bundles/ragents.lsp-roslyn/server/index.js +54 -15
  88. package/bundles/ragents.lsp-roslyn/server/index.js.map +4 -4
  89. package/bundles/ragents.lsp-typescript/executor/index.mjs +49 -0
  90. package/bundles/ragents.lsp-typescript/executor/index.mjs.map +7 -0
  91. package/bundles/ragents.lsp-typescript/ragents-bundle.json +5 -7
  92. package/bundles/ragents.lsp-typescript/server/index.js +22 -2
  93. package/bundles/ragents.lsp-typescript/server/index.js.map +3 -3
  94. package/bundles/ragents.model-relay/ragents-bundle.json +4 -4
  95. package/bundles/ragents.model-relay/server/index.js +3 -2
  96. package/bundles/ragents.model-relay/server/index.js.map +2 -2
  97. package/bundles/ragents.orchestration/ragents-bundle.json +4 -4
  98. package/bundles/ragents.orchestration/web/classes.json +1 -1
  99. package/bundles/ragents.orchestration/web/index.js +6 -6
  100. package/bundles/ragents.orchestration/web/index.js.map +3 -3
  101. package/bundles/ragents.overseer/ragents-bundle.json +4 -4
  102. package/bundles/ragents.overseer/server/index.js +1 -1
  103. package/bundles/ragents.overseer/server/index.js.map +2 -2
  104. package/bundles/ragents.processes/ragents-bundle.json +3 -3
  105. package/bundles/ragents.product/ragents-bundle.json +3 -3
  106. package/bundles/ragents.profile-distribution/ragents-bundle.json +4 -4
  107. package/bundles/ragents.profile-distribution/server/index.js +1 -1
  108. package/bundles/ragents.profile-distribution/server/index.js.map +2 -2
  109. package/bundles/ragents.reference/ragents-bundle.json +3 -3
  110. package/bundles/ragents.todo/ragents-bundle.json +3 -3
  111. package/bundles/ragents.transcript/ragents-bundle.json +3 -3
  112. package/bundles/ragents.watch/ragents-bundle.json +3 -3
  113. package/bundles/ragents.workspace/ragents-bundle.json +11 -5
  114. package/bundles/ragents.workspace/server/index.js +105 -30
  115. package/bundles/ragents.workspace/server/index.js.map +3 -3
  116. package/bundles/ragents.workspace/web/classes.json +1 -1
  117. package/bundles/ragents.workspace/web/index.js +1 -1
  118. package/bundles/ragents.workspace/web/index.js.map +3 -3
  119. package/package.json +3 -3
  120. package/packages/agent/dist/core/agent-settings.d.ts +1 -7
  121. package/packages/agent/dist/core/compaction/compaction.d.ts +17 -13
  122. package/packages/agent/dist/core/model-runtime.d.ts +5 -4
  123. package/packages/agent/dist/core/provider-composer.d.ts +2 -1
  124. package/packages/agent/dist/core/tools/bash.d.ts +9 -3
  125. package/packages/agent/dist/index.d.ts +1 -1
  126. package/packages/agent/src/core/agent-settings.ts +1 -4
  127. package/packages/agent/src/core/compaction/compaction.ts +68 -30
  128. package/packages/agent/src/core/model-runtime.ts +12 -5
  129. package/packages/agent/src/core/provider-composer.ts +5 -0
  130. package/packages/agent/src/core/tools/bash.ts +36 -30
  131. package/packages/agent/src/index.ts +3 -0
  132. package/packages/ai/dist/types.d.ts +11 -0
  133. package/packages/ai/src/types.ts +12 -0
  134. package/packages/ragents/src/domain/event-semantics.ts +3 -0
  135. package/packages/ragents/src/domain/event-validation.ts +15 -2
  136. package/packages/ragents/src/domain/events.ts +3 -0
  137. package/packages/ragents/src/domain/model.ts +2 -0
  138. package/packages/ragents/src/domain/projection.ts +1 -0
  139. package/packages/ragents/src/drivers/agent-runtime.ts +1 -1
  140. package/packages/ragents/src/drivers/agent-turn.ts +8 -6
  141. package/packages/ragents/src/index.ts +1 -0
  142. package/packages/ragents/src/plugin-host.ts +46 -0
  143. package/packages/ragents/src/plugin-types.ts +19 -0
  144. package/packages/ragents/src/runtime/decisions/inputs.ts +6 -2
  145. package/packages/ragents/src/runtime/journal-storage.ts +5 -4
  146. package/packages/workspace-executor/package.json +0 -1
  147. package/packages/workspace-executor/src/bash-launch.ts +56 -10
  148. package/packages/workspace-executor/src/context.ts +4 -0
  149. package/packages/workspace-executor/src/contributions.ts +150 -0
  150. package/packages/workspace-executor/src/executor.ts +1 -1
  151. package/packages/workspace-executor/src/index.ts +16 -19
  152. package/packages/workspace-executor/src/language-server/host.ts +3 -0
  153. package/packages/workspace-executor/src/language-server/module.ts +12 -2
  154. package/packages/workspace-executor/src/language-server/roots.ts +0 -5
  155. package/packages/workspace-executor/src/managed-process.ts +28 -0
  156. package/packages/workspace-executor/src/modules.ts +7 -6
  157. package/packages/workspace-executor/src/sandbox-tools.ts +12 -12
  158. package/packages/workspace-executor/src/shell-platform.ts +14 -3
  159. package/packages/workspace-executor/src/tools.ts +0 -3
  160. package/plugins/ragents.actor-programs/server/access-projections.ts +31 -0
  161. package/plugins/ragents.actor-programs/server/index.ts +2 -0
  162. package/plugins/ragents.ask/ask-payload.ts +9 -0
  163. package/plugins/ragents.ask/server/ask-service.ts +53 -13
  164. package/plugins/ragents.ask/web/AskActionView.tsx +3 -2
  165. package/plugins/ragents.ask/web/index.tsx +0 -6
  166. package/plugins/ragents.browser/executor/index.ts +5 -0
  167. package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/module.ts +25 -31
  168. package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/playwright.ts +9 -23
  169. package/plugins/ragents.browser/provision.ts +1 -1
  170. package/plugins/ragents.browser/server/browser.ts +3 -3
  171. package/plugins/ragents.browser/server/contract.ts +2 -2
  172. package/plugins/ragents.browser/server/index.ts +1 -1
  173. package/plugins/ragents.lsp-fsharp/executor.ts +80 -0
  174. package/plugins/ragents.lsp-fsharp/provision.ts +1 -1
  175. package/plugins/ragents.lsp-fsharp/server/index.ts +2 -2
  176. package/plugins/ragents.lsp-roslyn/executor.ts +64 -0
  177. package/plugins/ragents.lsp-roslyn/provision.ts +1 -1
  178. package/plugins/ragents.lsp-roslyn/server/index.ts +28 -5
  179. package/plugins/ragents.lsp-roslyn/server/solution-on-start.ts +18 -6
  180. package/plugins/ragents.lsp-typescript/executor.ts +50 -0
  181. package/plugins/ragents.lsp-typescript/server/index.ts +2 -2
  182. package/plugins/ragents.model-relay/server/config.ts +1 -1
  183. package/plugins/ragents.model-relay/server/relay.ts +4 -2
  184. package/plugins/ragents.orchestration/web/ActorTile.tsx +1 -1
  185. package/plugins/ragents.orchestration/web/run-panel/RunPanel.tsx +8 -7
  186. package/plugins/ragents.orchestration/web/run-panel/sheet-status.ts +3 -3
  187. package/plugins/ragents.overseer/server/api.ts +2 -2
  188. package/plugins/ragents.profile-distribution/server/archive.ts +2 -1
  189. package/plugins/ragents.workspace/client/workspace-client.ts +128 -32
  190. package/plugins/ragents.workspace/contract.ts +33 -2
  191. package/plugins/ragents.workspace/server/binding.ts +10 -4
  192. package/plugins/ragents.workspace/server/clients.ts +56 -9
  193. package/plugins/ragents.workspace/server/config.ts +12 -0
  194. package/plugins/ragents.workspace/server/index.ts +15 -5
  195. package/plugins/ragents.workspace/server/runtime.ts +10 -0
  196. package/plugins/ragents.workspace/server/shell-platform.ts +6 -5
  197. package/plugins/ragents.workspace/web/WorkspaceBinding.tsx +1 -1
  198. package/ragents.config.core.ts +4 -1
  199. package/ragents.config.showcase.ts +4 -1
  200. package/scripts/agent/journal.ts +3 -1
  201. package/scripts/package/build-package.ts +3 -1
  202. package/scripts/provision/run-provision.ts +2 -2
  203. package/scripts/workspace-client/run-workspace-client.ts +7 -4
  204. package/apps/web/dist/assets/main-C7JeZFjs.js +0 -6
  205. package/apps/web/dist/assets/mermaid-HWGCJPDP-DfsU5ofC.js +0 -478
  206. package/apps/web/dist/help/screenshots/release-checklist-vscode.png +0 -0
  207. package/apps/web/dist/help/screenshots/release-checklist-web.png +0 -0
  208. package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js +0 -2
  209. package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js.map +0 -7
  210. package/bundles/ragents.browser/server/chunks/chunk-2GKLLCBE.js.map +0 -7
  211. package/packages/workspace-executor/src/language-server/adapters/fsharp.ts +0 -60
  212. package/packages/workspace-executor/src/language-server/adapters/index.ts +0 -7
  213. package/packages/workspace-executor/src/language-server/adapters/roslyn.ts +0 -56
  214. package/packages/workspace-executor/src/language-server/adapters/typescript.ts +0 -74
  215. package/packages/workspace-executor/src/language-server/solution.ts +0 -13
  216. package/plugins/ragents.ask/web/QuestionSection.tsx +0 -48
  217. /package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/contract.ts +0 -0
  218. /package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/pages.ts +0 -0
@@ -2,6 +2,7 @@ import { statSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { Type } from "typebox";
4
4
  import { DomainError, type JsonValue, type RunState, type StartOptionContribution } from "@ragents/engine";
5
+ import type { ShellTools } from "@ragents/workspace-executor";
5
6
  import { shellPlatformChapter } from "./shell-platform.js";
6
7
  import { storedStartOption } from "@ragents/host/ragents/start-option-state.js";
7
8
  import type { WorkspaceResolver } from "@ragents/host/ragents/workspace-runtime.js";
@@ -87,13 +88,18 @@ export const serverDirectoryFolder = (directory: string): ExistingWorkspaceFolde
87
88
  return { path: resolved };
88
89
  };
89
90
 
90
- /** Die Bash eines Runs läuft auf dem Executor seiner Bindung; der Prompt nennt deshalb dessen Plattform, nicht die des Servers. */
91
- export const executorShellChapter = (registry: WorkspaceClientRegistry, owner: string | null, binding: WorkspaceBinding): string => {
91
+ /** Die Bash eines Runs läuft auf dem Executor seiner Bindung; der Prompt nennt deshalb dessen Plattform und Werkzeuge, nicht die des Servers. */
92
+ export const executorShellChapter = (
93
+ registry: WorkspaceClientRegistry,
94
+ owner: string | null,
95
+ binding: WorkspaceBinding,
96
+ serverTools: ShellTools,
97
+ ): string => {
92
98
  const { machine } = binding;
93
- if (machine === "server") return shellPlatformChapter(process.platform);
99
+ if (machine === "server") return shellPlatformChapter(process.platform, serverTools);
94
100
  const client = registry.info(owner, machine.client);
95
101
  return client
96
- ? shellPlatformChapter(client.platform as NodeJS.Platform)
102
+ ? shellPlatformChapter(client.platform as NodeJS.Platform, { ripgrep: client.ripgrep })
97
103
  : `## Shell platform\n\nThe workstation ${machine.label} that holds this project is not registered right now, `
98
104
  + "so the platform of its shell is unknown; the workspace tools fail until it connects again.";
99
105
  };
@@ -1,8 +1,10 @@
1
+ import { Value } from "typebox/value";
1
2
  import {
2
3
  DomainError,
3
4
  RPC_ERROR_CODES,
4
5
  RpcError,
5
6
  implement,
7
+ schemaComplaints,
6
8
  type AccessContext,
7
9
  type MethodConnection,
8
10
  type MethodContribution,
@@ -10,11 +12,13 @@ import {
10
12
  import {
11
13
  WORKSPACE_EXECUTOR_VERSION,
12
14
  sandboxRunEnvironment,
15
+ type ExecutorContributionStand,
13
16
  type WorkspaceExecuteOptions,
14
17
  type WorkspaceExecutor,
15
18
  } from "@ragents/workspace-executor";
16
19
  import {
17
20
  WORKSPACE_CLIENT_STOP_OPERATION,
21
+ clientRegistrationSchema,
18
22
  workspaceClientContracts,
19
23
  workspaceContracts,
20
24
  type WorkspaceClientDescription,
@@ -75,6 +79,35 @@ const messageOf = (cause: unknown): string => cause instanceof Error ? cause.mes
75
79
  /** Ein Arbeitsplatz ist erst durch Besitzer und Kennung bestimmt; zwei Benutzer mit derselben Kennung teilen nichts. */
76
80
  const keyOf = (owner: string | null, id: string): string => JSON.stringify([owner, id]);
77
81
 
82
+ /** Server und Arbeitsplatz brauchen denselben Executor; die Meldung sagt, wer von beiden zu alt ist. */
83
+ const assertExecutor = (label: string, executor: string): void => {
84
+ if (executor === WORKSPACE_EXECUTOR_VERSION) return;
85
+ const action = Number(executor) > Number(WORKSPACE_EXECUTOR_VERSION)
86
+ ? "Den Server auf die Fassung des Arbeitsplatzes aktualisieren."
87
+ : "Die RAgents-Erweiterung in VS Code beziehungsweise das Paket @schlenkr/ragents auf dem Arbeitsplatz aktualisieren.";
88
+ throw new DomainError(
89
+ "workspace-executor-version",
90
+ `Der Arbeitsplatz ${label} bringt den Executor ${executor} mit, der Server verlangt ${WORKSPACE_EXECUTOR_VERSION}. ${action}`,
91
+ 409,
92
+ );
93
+ };
94
+
95
+ const described = (contributions: readonly ExecutorContributionStand[]): string =>
96
+ contributions.map(({ plugin, stand }) => `${plugin} (${stand.slice(0, 12)})`).join(", ") || "keine";
97
+
98
+ /** Ein Arbeitsplatz führt aus, was die Plugins des Servers beitragen; mit anderen Beiträgen liefen dieselben Werkzeuge dort anders als auf dem Server. */
99
+ const assertContributions = (label: string, expected: readonly ExecutorContributionStand[], given: readonly ExecutorContributionStand[]): void => {
100
+ const key = (entry: ExecutorContributionStand): string => `${entry.plugin}\0${entry.stand}`;
101
+ const same = expected.length === given.length && expected.every((entry) => given.some((other) => key(other) === key(entry)));
102
+ if (same) return;
103
+ throw new DomainError(
104
+ "workspace-executor-contributions",
105
+ `Der Arbeitsplatz ${label} bringt die Executor-Beiträge ${described(given)} mit, der Server verlangt ${described(expected)}. `
106
+ + "Der Arbeitsplatz fragt sie mit ragents.workspace.clients.contributions ab und meldet sich danach erneut an.",
107
+ 409,
108
+ );
109
+ };
110
+
78
111
  /** Über das Netz nimmt der Server Arbeitsplätze nur von angemeldeten Benutzern an; ohne Benutzer gäbe es nur einen Besitzer für alle Zugänge. */
79
112
  export const assertMayRegister = (access: AccessContext, local: boolean): void => {
80
113
  if (local || (access.enabled && access.user !== null)) return;
@@ -88,27 +121,29 @@ export const assertMayRegister = (access: AccessContext, local: boolean): void =
88
121
 
89
122
  /** Kennt die angemeldeten Arbeitsplätze je Besitzer, hält je Client die Verbindung, über die der Server ihn zurückruft, und die Stopps, die ihn nicht erreicht haben. */
90
123
  export class WorkspaceClientRegistry {
124
+ /** Was die Plugins des Servers zum Executor beitragen; jeder Arbeitsplatz muss genau diese Beiträge tragen. */
125
+ readonly contributions: readonly ExecutorContributionStand[];
91
126
  readonly #clients = new Map<string, ClientEntry>();
92
127
  /** Stopps, die den Arbeitsplatz noch nicht erreicht haben, je Arbeitsplatz und Run mit dem Ordner der Bindung. */
93
128
  readonly #pendingStops = new Map<string, Map<string, string>>();
94
129
  readonly #stopRetries = new Map<string, NodeJS.Timeout>();
95
130
 
131
+ constructor(contributions: readonly ExecutorContributionStand[]) {
132
+ this.contributions = contributions.map(({ plugin, stand }) => ({ plugin, stand }));
133
+ }
134
+
96
135
  async register(
97
136
  id: string,
98
137
  description: WorkspaceClientDescription,
99
138
  executor: string,
139
+ contributions: readonly ExecutorContributionStand[],
100
140
  connection: MethodConnection,
101
141
  ): Promise<WorkspaceClientInfo> {
102
142
  if (connection.streamless) {
103
143
  throw new DomainError("stream-required", "Die Anmeldung eines Arbeitsplatzes braucht einen Ereignisstrom.", 409);
104
144
  }
105
- if (executor !== WORKSPACE_EXECUTOR_VERSION) {
106
- throw new DomainError(
107
- "workspace-executor-version",
108
- `Der Arbeitsplatz ${description.label} bringt den Executor ${executor} mit, der Server verlangt ${WORKSPACE_EXECUTOR_VERSION}.`,
109
- 409,
110
- );
111
- }
145
+ assertExecutor(description.label, executor);
146
+ assertContributions(description.label, this.contributions, contributions);
112
147
  const owner = connection.userId;
113
148
  const key = keyOf(owner, id);
114
149
  const previous = this.#clients.get(key);
@@ -318,9 +353,21 @@ export class WorkspaceClientRegistry {
318
353
 
319
354
  export const clientMethods = (registry: WorkspaceClientRegistry): MethodContribution[] => [
320
355
  implement(workspaceContracts.clients.list, (_input, { access }) => registry.list(ownerOf(access))),
321
- implement(workspaceContracts.clients.register, ({ id, executor, ...description }, { access, connection, local }) => {
356
+ implement(workspaceContracts.clients.contributions, ({ label, executor }, { access, local }) => {
322
357
  assertMayRegister(access, local);
323
- return registry.register(id, description, executor, connection);
358
+ assertExecutor(label, executor);
359
+ return registry.contributions.map((entry) => ({ ...entry }));
360
+ }),
361
+ implement(workspaceContracts.clients.register, (input, { access, connection, local }) => {
362
+ assertMayRegister(access, local);
363
+ // Erst der Stand: ein Arbeitsplatz mit einem anderen kennt die Form dieses Stands nicht, mit diesem gilt sie ganz.
364
+ assertExecutor(input.label, input.executor);
365
+ if (!Value.Check(clientRegistrationSchema, input)) {
366
+ throw new RpcError(RPC_ERROR_CODES.invalidParams,
367
+ `Ungültige Eingabe für ${workspaceContracts.clients.register.id}: ${schemaComplaints(clientRegistrationSchema, input, "params")}`);
368
+ }
369
+ const { id, executor, contributions, ...description } = input;
370
+ return registry.register(id, description, executor, contributions, connection);
324
371
  }),
325
372
  implement(workspaceContracts.clients.unregister, ({ id }, { access, connection }) => {
326
373
  registry.unregister(ownerOf(access), id, connection);
@@ -5,6 +5,8 @@ export const workspaceConfigDescriptors = [
5
5
  { key: "PROCESS_SANDBOX", source: "environment" },
6
6
  { key: "PROCESS_SANDBOX_NETWORK", source: "environment" },
7
7
  { key: "RAGENTS_BASH", source: "environment" },
8
+ { key: "RAGENTS_RG", source: "environment" },
9
+ { key: "RAGENTS_BASH_TIMEOUT_SECONDS", source: "environment" },
8
10
  ] as const;
9
11
 
10
12
  const env = declaredEnvironment(workspaceConfigDescriptors);
@@ -14,6 +16,9 @@ export interface ProcessSandboxSetting {
14
16
  readonly network: readonly string[];
15
17
  }
16
18
 
19
+ /** So schaltet der Betreiber die Prozess-Sandbox in der Profildatei ab. */
20
+ export const PROCESS_SANDBOX_OFF = 'PROCESS_SANDBOX: "off" in der Sektion ragents.workspace';
21
+
17
22
  /** Ohne Angabe ist die Sandbox an; abschalten geht nur ausdrücklich mit "off". */
18
23
  export const processSandboxSetting = (): ProcessSandboxSetting => {
19
24
  const mode = env.optional("PROCESS_SANDBOX") ?? "on";
@@ -28,3 +33,10 @@ export const processSandboxSetting = (): ProcessSandboxSetting => {
28
33
 
29
34
  /** Die Bash, mit der der Executor dieses Servers das Werkzeug bash startet; unter Windows setzt sie die VS-Code-Erweiterung für ihren lokalen Host. */
30
35
  export const bashSetting = (): string | undefined => env.optional("RAGENTS_BASH") || undefined;
36
+
37
+ /** Das rg, das der Executor dieses Servers vorn in den PATH der Bash setzt; die VS-Code-Erweiterung setzt es für ihren lokalen Host. */
38
+ export const rgSetting = (): string | undefined => env.optional("RAGENTS_RG") || undefined;
39
+
40
+ /** Die Zeitgrenze von bash in Sekunden für Aufrufe ohne eigene; mehr als die größte, die ein Aufruf nennen darf, lehnt das Werkzeug beim Start ab. */
41
+ export const bashTimeoutSetting = (): number | undefined =>
42
+ env.optional("RAGENTS_BASH_TIMEOUT_SECONDS") ? env.positiveNumber("RAGENTS_BASH_TIMEOUT_SECONDS", "") : undefined;
@@ -4,6 +4,7 @@ import { documentStoreToken } from "@ragents/host/ragents/document-store.js";
4
4
  import { workspaceResolverToken, workspaceRuntimeToken, type WorkspaceResolver } from "@ragents/host/ragents/workspace-runtime.js";
5
5
  import { sandboxServicesToken } from "@ragents/host/plugin-support/workspace-sandbox-host.js";
6
6
  import {
7
+ executorContributionsToken,
7
8
  hostAddressToken,
8
9
  runtimeProviderToken,
9
10
  runGuardToken,
@@ -12,6 +13,7 @@ import {
12
13
  } from "@ragents/host/ragents/host-services.js";
13
14
  import { pluginAsset } from "@ragents/host/plugin-support/plugin-folder.js";
14
15
  import { ServerProcessSandbox } from "@ragents/host/plugin-support/process-sandbox.js";
16
+ import { ripgrepAvailable } from "@ragents/workspace-executor";
15
17
  import type { PluginModule } from "@ragents/host/plugin-support/plugin-module.js";
16
18
  import { boundToTools, handlebarsPrompt } from "@ragents/host/plugin-support/prompt.js";
17
19
  import { shellPlatformPrompt } from "./shell-platform.js";
@@ -21,11 +23,11 @@ import { WORKSPACE_BINDING_OPTION_ID, WORKSPACE_METADATA_ID } from "../contract.
21
23
  import { bindingOf, executorShellChapter, sessionMetadataOf, workspaceBindingOption, workspaceLocation, workspaceOwnerOf } from "./binding.js";
22
24
  import { createBrowseChannel, createBrowseMethods } from "./browse-route.js";
23
25
  import { clientMethods, WorkspaceClientRegistry } from "./clients.js";
24
- import { bashSetting, processSandboxSetting, workspaceConfigDescriptors } from "./config.js";
26
+ import { bashSetting, bashTimeoutSetting, PROCESS_SANDBOX_OFF, processSandboxSetting, rgSetting, workspaceConfigDescriptors } from "./config.js";
25
27
  import { RunWorkspaceRuntime } from "./runtime.js";
26
28
 
27
29
  const warnWithoutSandbox = (): void => {
28
- console.warn("Prozess-Sandbox ausgeschaltet (PROCESS_SANDBOX: \"off\" in der Sektion ragents.workspace): Prozesse der Runs laufen auf dem Server ohne Sandbox.");
30
+ console.warn(`Prozess-Sandbox ausgeschaltet (${PROCESS_SANDBOX_OFF}): Prozesse der Runs laufen auf dem Server ohne Sandbox.`);
29
31
  };
30
32
 
31
33
  const ragentsWorkspacePlugin = (skillPaths: () => Promise<readonly string[]>): RAgentsPlugin => ({
@@ -48,7 +50,8 @@ const ragentsWorkspacePlugin = (skillPaths: () => Promise<readonly string[]>): R
48
50
  if (!directory) throw new Error("In diesem Profil gibt es keine Dateiablage; das Plugin ragents.documents fehlt");
49
51
  return directory;
50
52
  };
51
- const clients = new WorkspaceClientRegistry();
53
+ const contributions = host.service(executorContributionsToken);
54
+ const clients = new WorkspaceClientRegistry(contributions);
52
55
  const contribution = (): WorkspaceResolver | undefined => host.optionalService(workspaceResolverToken);
53
56
  host.config(...workspaceConfigDescriptors);
54
57
  const sandboxSetting = processSandboxSetting();
@@ -57,13 +60,20 @@ const ragentsWorkspacePlugin = (skillPaths: () => Promise<readonly string[]>): R
57
60
  network: sandboxSetting.network,
58
61
  serverAddress: host.service(hostAddressToken)(),
59
62
  dataDirectory: path.dirname(host.storage.sessionsRoot),
63
+ disableSetting: PROCESS_SANDBOX_OFF,
60
64
  })
61
65
  : undefined;
62
66
  const bash = bashSetting();
67
+ const rg = rgSetting();
68
+ const bashTimeoutSeconds = bashTimeoutSetting();
69
+ const serverTools = { ripgrep: ripgrepAvailable(rg, process.env) };
63
70
  const runtime = new RunWorkspaceRuntime({
64
71
  clients,
72
+ contributions: contributions.map((contribution) => contribution.parts),
65
73
  ...(processSandbox ? { processSandbox } : {}),
66
74
  ...(bash === undefined ? {} : { bash }),
75
+ ...(rg === undefined ? {} : { rg }),
76
+ ...(bashTimeoutSeconds === undefined ? {} : { bashTimeoutSeconds }),
67
77
  globalDirectory: host.storage.root(),
68
78
  sessionDirectory: (runId, ...segments) => host.storage.session(runId, ...segments),
69
79
  storageRootFor: (runId) => path.join(host.storage.sessionsRoot, runId),
@@ -92,9 +102,9 @@ const ragentsWorkspacePlugin = (skillPaths: () => Promise<readonly string[]>): R
92
102
  // Die Regeln gelten für die Arbeitsbereiche des Hosts; eine beigesteuerte Art beschreibt ihre eigenen.
93
103
  render: (context) => contribution()?.kind ? "" : rules.render(context),
94
104
  }, ...agentWorkspaceToolNames),
95
- shellPlatformPrompt("ragents.workspace.shell.prompt", 102, (runId) => {
105
+ shellPlatformPrompt("ragents.workspace.shell.prompt", 102, serverTools, (runId) => {
96
106
  const state = runState(runId);
97
- return executorShellChapter(clients, workspaceOwnerOf(state), bindingOf(state));
107
+ return executorShellChapter(clients, workspaceOwnerOf(state), bindingOf(state), serverTools);
98
108
  }),
99
109
  );
100
110
  const browseOptions = {
@@ -8,6 +8,7 @@ import {
8
8
  type SandboxHomeEnvironment,
9
9
  type WorkspaceExecuteOptions,
10
10
  type WorkspaceExecutor,
11
+ type WorkspaceExecutorParts,
11
12
  } from "@ragents/workspace-executor";
12
13
  import type {
13
14
  SessionWorkspace,
@@ -46,10 +47,16 @@ export interface RunWorkspaceRuntimeOptions {
46
47
  runState: (runId: string) => RunState | null;
47
48
  storeBinding: (runId: string, binding: WorkspaceBinding) => void;
48
49
  clients: WorkspaceClientRegistry;
50
+ /** Was die Plugins des Profils zum Executor des Servers beitragen; die Arbeitsplätze laden dieselben Beiträge selbst. */
51
+ contributions: readonly WorkspaceExecutorParts[];
49
52
  /** Die Prozess-Sandbox des Servers; ohne sie laufen die Prozesse des Servers ohne. */
50
53
  processSandbox?: RunProcessSandboxes;
51
54
  /** Die Bash des Servers aus RAGENTS_BASH; unter Windows Pflicht für das Werkzeug bash. */
52
55
  bash?: string;
56
+ /** Das rg des Servers aus RAGENTS_RG; ohne Angabe gilt eines im PATH. */
57
+ rg?: string;
58
+ /** Die Zeitgrenze von bash aus RAGENTS_BASH_TIMEOUT_SECONDS; ohne Angabe die des Werkzeugs. */
59
+ bashTimeoutSeconds?: number;
53
60
  }
54
61
 
55
62
  const runNotStarted = (): DomainError => new DomainError(
@@ -141,6 +148,7 @@ export class RunWorkspaceRuntime implements WorkspaceRuntime {
141
148
  this.#nugetCacheDirectory = path.join(options.globalDirectory, "nuget-cache");
142
149
  this.sandbox = new WorkspaceSandboxHost({
143
150
  contributorName: "ragents.workspace.sandbox",
151
+ contributions: options.contributions,
144
152
  workspaceFor: options.sessionWorkspaceFor,
145
153
  identFor: () => Promise.resolve(undefined),
146
154
  skillPaths: options.skillPaths,
@@ -150,6 +158,8 @@ export class RunWorkspaceRuntime implements WorkspaceRuntime {
150
158
  serverDirectoryFor: (runId) => this.#serverDirectoryFor(runId),
151
159
  ...(options.processSandbox ? { processSandbox: options.processSandbox } : {}),
152
160
  ...(options.bash === undefined ? {} : { bash: options.bash }),
161
+ ...(options.rg === undefined ? {} : { rg: options.rg }),
162
+ ...(options.bashTimeoutSeconds === undefined ? {} : { bashTimeoutSeconds: options.bashTimeoutSeconds }),
153
163
  });
154
164
  }
155
165
 
@@ -1,19 +1,20 @@
1
1
  import type { PromptContribution } from "@ragents/engine";
2
- import { shellPlatformText } from "@ragents/workspace-executor";
2
+ import { shellPlatformText, type ShellTools } from "@ragents/workspace-executor";
3
3
  import { boundToTools } from "@ragents/host/plugin-support/prompt.js";
4
4
 
5
- export const shellPlatformChapter = (platform: NodeJS.Platform): string =>
6
- `## Shell platform\n\n${shellPlatformText(platform)}`;
5
+ export const shellPlatformChapter = (platform: NodeJS.Platform, tools: ShellTools): string =>
6
+ `## Shell platform\n\n${shellPlatformText(platform, tools)}`;
7
7
 
8
- /** Ohne Angabe gilt die Plattform des Servers; `chapterFor` nennt die des Executors, der den Run ausführt. */
8
+ /** Ohne Angabe gelten Plattform und Werkzeuge des Servers; `chapterFor` nennt die des Executors, der den Run ausführt. */
9
9
  export const shellPlatformPrompt = (
10
10
  id: string,
11
11
  order: number,
12
+ serverTools: ShellTools,
12
13
  chapterFor?: (runId: string) => string,
13
14
  ): PromptContribution => boundToTools({
14
15
  id,
15
16
  order,
16
17
  delivery: "initial",
17
- render: () => shellPlatformChapter(process.platform),
18
+ render: () => shellPlatformChapter(process.platform, serverTools),
18
19
  ...(chapterFor ? { renderForRun: chapterFor } : {}),
19
20
  }, "bash");
@@ -42,7 +42,7 @@ const isClientInfo = (value: unknown): value is WorkspaceClientInfo => {
42
42
  && typeof raw.id === "string" && typeof raw.label === "string"
43
43
  && typeof raw.hostname === "string" && typeof raw.platform === "string"
44
44
  && Array.isArray(raw.folders) && raw.folders.every((folder) => typeof folder === "string")
45
- && typeof raw.runsDirectory === "string";
45
+ && typeof raw.runsDirectory === "string" && typeof raw.ripgrep === "boolean";
46
46
  };
47
47
 
48
48
  const isFreshLabels = (value: unknown): value is FreshWorkspaceLabels => {
@@ -6,7 +6,10 @@ export const config = {
6
6
  PRODUCT_PROFILE: "core",
7
7
  COMPACTION_MODEL: "google/gemma-4-26b-a4b-it",
8
8
  // Aliasse für andere RAgents-Server, die ihre Modelle über ragents.model-relay von hier beziehen.
9
- MODEL_ALIASES: ["core-standard=openrouter/z-ai/glm-5.3-flash", "core-coordinator=openrouter/deepseek/deepseek-v4-flash-0731"],
9
+ MODEL_ALIASES: [
10
+ { alias: "core-standard", model: "openrouter/z-ai/glm-5.3-flash", compaction: { threshold: 160_000, keepRecentTokens: 24_000, summaryTokens: 12_000 } },
11
+ { alias: "core-coordinator", model: "openrouter/deepseek/deepseek-v4-flash-0731", compaction: { threshold: 300_000, keepRecentTokens: 40_000, summaryTokens: 16_000 } },
12
+ ],
10
13
  PRODUCT_ID: "ragents",
11
14
  PRODUCT_TITLE: "RAgents",
12
15
  PLUGINS: [
@@ -7,7 +7,10 @@ export const config = {
7
7
  PRODUCT_PROFILE: "showcase",
8
8
  COMPACTION_MODEL: "google/gemma-4-26b-a4b-it",
9
9
  // Aliasse für andere RAgents-Server, die ihre Modelle über ragents.model-relay von hier beziehen.
10
- MODEL_ALIASES: ["showcase-standard=openrouter/z-ai/glm-5.3-flash", "showcase-coordinator=openrouter/deepseek/deepseek-v4-flash-0731"],
10
+ MODEL_ALIASES: [
11
+ { alias: "showcase-standard", model: "openrouter/z-ai/glm-5.3-flash", compaction: { threshold: 160_000, keepRecentTokens: 24_000, summaryTokens: 12_000 } },
12
+ { alias: "showcase-coordinator", model: "openrouter/deepseek/deepseek-v4-flash-0731", compaction: { threshold: 300_000, keepRecentTokens: 40_000, summaryTokens: 16_000 } },
13
+ ],
11
14
  PRODUCT_ID: "ragents-showcase",
12
15
  PRODUCT_TITLE: "RAgents Showcase",
13
16
  PLUGINS: [
@@ -114,7 +114,9 @@ export const journalLines = (events: readonly JournalEvent[], mode: JournalMode,
114
114
  const content = payload.subscriptionId ? `[event ${String((payload.sourceEventIds as string[] | undefined)?.[0] ?? "")}]` : text(payload.content);
115
115
  lines.push(`[${event.sequence}] INPUT -> ${String(payload.actorId ?? "").slice(0, 14)}: ${content.slice(0, 300)}`);
116
116
  } else if (type === "context.compacted" && mode !== "tools") {
117
- lines.push(`[${event.sequence}] CONTEXT COMPACTED ${actor}: about ${String(payload.tokensBefore)} tokens summarized`);
117
+ const threshold = payload.threshold as { tokens?: unknown; source?: unknown } | undefined;
118
+ const applied = threshold ? ` (threshold ${String(threshold.tokens)} from ${String(threshold.source)})` : "";
119
+ lines.push(`[${event.sequence}] CONTEXT COMPACTED ${actor}: about ${String(payload.tokensBefore)} tokens summarized${applied}`);
118
120
  } else if (type === "turn.input-steered" && mode !== "tools") {
119
121
  lines.push(`[${event.sequence}] STEERING -> ${actor}: ${String(payload.inputId ?? "")} in ${String(payload.turnId ?? "")}`);
120
122
  } else if (type.startsWith("tool.call.") && mode !== "chat") {
@@ -84,6 +84,8 @@ const PACKAGE_NAME_PATTERN = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._
84
84
  const SCAN_SKIPPED = new Set(["node_modules", "dist"]);
85
85
  const SCANNED_EXTENSIONS = new Set([".ts", ".tsx", ".mts", ".mjs", ".js", ".css"]);
86
86
  const IMPORT_PATTERN = /\b(?:from|import|require(?:\.resolve)?)\s*\(?\s*["']([^"'\n]+)["']/g;
87
+ /** Ein Beitrag zum Executor löst Pakete zur Laufzeit aus dem Host auf; auch sie muss das Paket tragen. */
88
+ const HOST_PACKAGE_PATTERN = /\bhostPackageFile\([^,()]*,\s*["']([^"'\n]+)["']/g;
87
89
 
88
90
  const files = async (folder: string, skippedFolders: ReadonlySet<string> = SKIPPED_FOLDERS): Promise<readonly string[]> => {
89
91
  const found: string[] = [];
@@ -149,7 +151,7 @@ export const requiredPackages = (packageDirectory: string): ReadonlyMap<string,
149
151
  for (const folder of scanRoots(packageDirectory)) {
150
152
  for (const file of scannedFiles(folder)) {
151
153
  const content = readFileSync(file, "utf8");
152
- for (const match of content.matchAll(IMPORT_PATTERN)) {
154
+ for (const match of [...content.matchAll(IMPORT_PATTERN), ...content.matchAll(HOST_PACKAGE_PATTERN)]) {
153
155
  const name = packageNameOf(match[1]!);
154
156
  if (name && !sources.has(name)) sources.set(name, path.relative(packageDirectory, file));
155
157
  }
@@ -19,8 +19,8 @@ const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url))
19
19
 
20
20
  const usage = (): string => `Verwendung: pnpm provision [<profil>|<pfad zu ragents.config.<profil>.ts>|--workspace]
21
21
  Provisioniert die Werkzeuge der Plugins eines Profils nach <Datenordner>/tools/<plugin-id>/ und
22
- berichtet je Plugin bereit, installiert oder fehlt. --workspace provisioniert stattdessen
23
- Sprachserver und Browser eines Arbeitsplatzes auf dieser Maschine. Ein relativer Pfad gilt ab dem
22
+ berichtet je Plugin bereit, installiert oder fehlt. --workspace provisioniert stattdessen die
23
+ eingebauten Plugins, die zum Executor eines Arbeitsplatzes beitragen. Ein relativer Pfad gilt ab dem
24
24
  aufrufenden Ordner; ohne Argument gilt das Profil aus der Umgebung (PRODUCT_PROFILE_FILE oder
25
25
  PRODUCT_PROFILE).`;
26
26
 
@@ -13,11 +13,13 @@ const usage = (): string => `Verwendung: [RAGENTS_TOKEN=<token>] pnpm workspace-
13
13
  Meldet die Ordner als Arbeitsplatz beim Server an und führt dessen Aufträge mit dem Executor
14
14
  dieses Rechners aus - dasselbe, was die VS-Code-Erweiterung tut, nur ohne VS Code. Ohne Ordner
15
15
  gilt das aktuelle Verzeichnis. Jeder Werkzeugaufruf erscheint als eine Zeile auf stdout.
16
- Sprachserver und Chromium holt der Start auf diesen Rechner (dasselbe wie pnpm provision
17
- --workspace); ROSLYN_LANGUAGE_SERVER, FSHARP_LANGUAGE_SERVER und BROWSER_EXECUTABLE_PATH
18
- übersteuern das, TypeScript und playwright-core kommen aus dem Host-Ordner. Unter Windows nennt
16
+ Was die Plugins des Servers zum Executor beitragen, etwa Sprachserver, lädt der Arbeitsplatz bei
17
+ der Anmeldung aus den Bundles dieses Hosts; ihre Werkzeuge holt der Start auf diesen Rechner
18
+ (dasselbe wie pnpm provision --workspace). Unter Windows nennt
19
19
  RAGENTS_BASH die bash.exe, die RAgents mitbringt (aus der Windows-Fassung der VS-Code-Erweiterung);
20
- ohne sie scheitert das Werkzeug bash. Das Skript läuft, bis es mit Strg-C beendet wird.`;
20
+ ohne sie scheitert das Werkzeug bash. RAGENTS_RG nennt ein rg, dessen Ordner die Bash vorn im PATH
21
+ hat, etwa das aus der Erweiterung; ohne Angabe gilt eines im PATH. Das Skript läuft, bis es mit
22
+ Strg-C beendet wird.`;
21
23
 
22
24
  export interface WorkspaceClientArguments {
23
25
  readonly serverUrl: string;
@@ -79,6 +81,7 @@ const main = async (): Promise<void> => {
79
81
  const client = new WorkspaceClient(transport, identity, {
80
82
  hostRoot,
81
83
  bash: process.env.RAGENTS_BASH || undefined,
84
+ rg: process.env.RAGENTS_RG || undefined,
82
85
  onExecuted: ({ runId, operation, durationMs, error }) =>
83
86
  console.log(`== ${runId.slice(0, 8)} ${operation} ${durationMs} ms ${error ?? "ok"}`),
84
87
  });
@@ -1,6 +0,0 @@
1
- import{a as De,r as t,j as e,D as oe,b as ce,d as G,B as b,X as Le,M as Pe,C as de,e as Me,f as Oe,g as He,h as Ie,u as Be,i as _e,k as Fe,l as Ue,m as Ke,A as Te,n as qe,o as We,p as $e,U as Qe,P as Ve,W as Ge,R as Xe,q as ae,s as V,t as Je,v as Ye,w as Ze,x as et,y as tt,z as st,F as nt,Q as rt,G as at,H as it}from"./mermaid-HWGCJPDP-DfsU5ofC.js";/**
2
- * @license lucide-react v1.46.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const ue={name:"circle-question-mark",size:24,node:[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],aliases:["help-circle","circle-help"]};ue.node;const lt=De(ue);function ot(n,r,a,u){if(!r||n.source!==r||n.origin!==a)return;const i=n.data;if(!(!i||typeof i!="object"||Array.isArray(i))&&"type"in i){if(i.type==="ragents:help-ready")return{type:"ready"};if(i.type==="ragents:start-sample"&&"entry"in i&&typeof i.entry=="string"&&u.includes(i.entry))return{type:"start",entry:i.entry}}}function ct({onClose:n,sampleEntries:r,onStartSample:a}){const u=t.useRef(null),i=t.useRef(null),h=t.useRef(void 0),x=t.useRef(!1);t.useEffect(()=>()=>{var l;return(l=h.current)==null?void 0:l.call(h)},[]),t.useEffect(()=>{var j;const l=(j=i.current)==null?void 0:j.contentWindow;if(!l)return;const o=()=>l.postMessage({type:"ragents:help-context",canStartSamples:r.length>0,entries:r},window.location.origin),p=C=>{const c=ot(C,l,window.location.origin,r);(c==null?void 0:c.type)==="ready"&&o(),(c==null?void 0:c.type)==="start"&&!x.current&&(x.current=!0,a(c.entry))};return window.addEventListener("message",p),o(),()=>window.removeEventListener("message",p)},[a,r]);const m=()=>{var C;(C=h.current)==null||C.call(h);const l=i.current,o=l==null?void 0:l.contentDocument,p=o==null?void 0:o.defaultView;if(!l||!o||!p)return;o.documentElement.dataset.helpEmbedded="true";for(const c of o.querySelectorAll("a[href]"))new URL(c.href).origin!==window.location.origin&&(c.target="_blank",c.rel="noopener noreferrer");const j=c=>{var v;if(!c.defaultPrevented){if(c.key==="Escape")c.preventDefault(),n();else if(c.key==="Tab"){const g=[...o.querySelectorAll("a[href], button, input, select, textarea, summary, [tabindex]")].filter(y=>y.tabIndex>=0&&!y.matches(":disabled")&&y.getClientRects().length>0),O=c.shiftKey?g[0]:g.at(-1);if(!g.length||o.activeElement===O||o.activeElement===o.body){if(!c.shiftKey&&o.activeElement===o.body&&g.length)return;c.preventDefault(),(v=u.current)==null||v.focus()}}}};p.addEventListener("keydown",j),h.current=()=>p.removeEventListener("keydown",j)};return e.jsx(oe,{open:!0,onOpenChange:l=>{l||n()},children:e.jsxs(ce,{className:"gap-0 p-0",initialFocus:u,scope:"page",showCloseButton:!1,size:"full",children:[e.jsx(G,{className:"sr-only",children:"Hilfe"}),e.jsx(b,{"aria-label":"Hilfe schließen",className:"absolute top-3 right-4.5 z-1 rounded-full",onClick:n,ref:u,size:"icon",variant:"outline",children:e.jsx(Le,{})}),e.jsx("iframe",{className:"min-h-0 w-full min-w-0 flex-[1_1_0] bg-background",onLoad:m,ref:i,src:"/help/index.html",tabIndex:0,title:"RAgents: Homepage und Dokumentation"})]})})}const dt="button:not([disabled]), a[href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex='-1'])",fe="pointer-events-auto shadow-pop";function ut({onBusy:n,onClose:r,onOpen:a,open:u,panels:i,registry:h,runs:x}){const m=t.useRef(null);return t.useEffect(()=>{if(!u)return;const l=requestAnimationFrame(()=>{var p;const o=m.current;!o||o.contains(document.activeElement)||(p=o.querySelector(dt))==null||p.focus({preventScroll:!0})});return()=>cancelAnimationFrame(l)},[u]),e.jsxs(Pe,{className:"pointer-events-none flex h-[min(900px,100%)] w-[min(1440px,100%)] flex-col rounded-none bg-transparent p-0 ring-0",keepMounted:!0,onClose:r,open:u,scope:"workspace",size:"full",children:[e.jsx(G,{className:"sr-only",children:"Übersicht"}),e.jsxs("div",{className:"flex min-h-0 min-w-0 flex-1 gap-4 max-[900px]:flex-col",id:"app-overview",ref:m,children:[i.map(({id:l,Panel:o})=>e.jsx(ft,{id:l,onBusy:n,onClose:r,onOpen:a,open:u,Panel:o,registry:h},l)),x&&e.jsx(ht,{...x})]})]})}function ft({id:n,onBusy:r,onClose:a,onOpen:u,open:i,Panel:h,registry:x}){const m=t.useCallback(l=>r(n,l),[n,r]);return t.useEffect(()=>()=>r(n,!1),[n,r]),e.jsx(de,{className:`${fe} min-h-0 min-w-0 flex-1 gap-0 p-0`,children:e.jsx(h,{onBusy:m,onClose:a,onOpen:u,open:i,registry:x})})}function ht({activeId:n,canCreate:r,canDelete:a,onCreate:u,onDelete:i,onOpen:h,registry:x,sessions:m,seenRevisions:l,unreachable:o}){const[p,j]=t.useState(),[C,c]=t.useState(!1),[v,g]=t.useState(()=>new Set),[O,y]=t.useState(!1),[N,B]=t.useState(!1),_=()=>{c(!1),g(new Set)},w=f=>{g(z=>{const H=new Set(z);return H.delete(f)||H.add(f),H})},E=async f=>{B(!0),j(void 0);try{await i(f)}catch(z){j(z instanceof Error?z.message:String(z))}finally{B(!1)}},S=async()=>{await E(m.filter(f=>v.has(f.id)).map(f=>f.id)),y(!1),_()};return e.jsx("section",{"aria-labelledby":"overview-runs-title",className:"flex min-h-0 min-w-0 flex-1 flex-col max-[900px]:flex-[1_1_50%]",children:e.jsxs(de,{className:`${fe} min-h-0 flex-1 gap-workspace-inset overflow-y-auto overscroll-contain pt-workspace-inset pr-6 pb-6 pl-6 max-[900px]:px-3 max-[900px]:pt-3.5 max-[900px]:pb-4`,children:[e.jsxs("header",{className:"flex flex-wrap items-center gap-x-3.5 gap-y-2.5",children:[e.jsxs("h2",{className:"text-[0.95rem] font-semibold",id:"overview-runs-title",children:["Runs ",e.jsx("span",{className:"ml-1 text-[0.8rem] font-medium tabular-nums text-muted-foreground",children:m.length})]}),o&&e.jsx("span",{className:"text-[0.72rem] font-medium text-destructive",role:"alert",children:"Server nicht erreichbar"}),a&&m.length>0&&e.jsx("div",{className:"ml-auto flex flex-wrap items-center gap-1",children:C?e.jsxs(e.Fragment,{children:[e.jsx(b,{onClick:()=>g(new Set(m.map(f=>f.id))),size:"sm",variant:"ghost",children:"Alle"}),e.jsx(b,{onClick:()=>g(new Set),size:"sm",variant:"ghost",children:"Keine"}),e.jsxs(b,{className:"ml-auto",disabled:v.size===0||N,onClick:()=>y(!0),size:"sm",variant:"destructive",children:["Löschen (",v.size,")"]}),e.jsx(b,{onClick:_,size:"sm",variant:"ghost",children:"Fertig"})]}):e.jsx(b,{onClick:()=>c(!0),size:"sm",variant:"ghost",children:"Auswählen"})})]}),p&&e.jsx("p",{className:"text-[0.72rem] font-medium text-destructive",role:"alert",children:p}),e.jsx("p",{className:"mb-5.5 text-[0.75rem] text-muted-foreground",children:"Nach letzter Aktivität im Run. Neue Aktivität ist seit Deinem letzten Ansehen hinzugekommen."}),e.jsx(Me,{seenRevisions:l,activeId:n,onCreate:r?u:void 0,onDelete:a?f=>void E([f]):void 0,onSelect:h,onToggleSelected:w,registry:x,selectMode:C,selectedIds:v,sessions:m}),O&&e.jsx(oe,{open:!0,onOpenChange:f=>{!f&&!N&&y(!1)},children:e.jsxs(ce,{scope:"page",showCloseButton:!1,size:"small",children:[e.jsxs(Oe,{children:[e.jsx(G,{children:"Runs löschen"}),e.jsx(He,{children:v.size===1?"Ein Run wird endgültig gelöscht.":`${v.size} Runs werden endgültig gelöscht.`})]}),e.jsxs(Ie,{children:[e.jsx(b,{disabled:N,onClick:()=>y(!1),variant:"outline",children:"Abbrechen"}),e.jsx(b,{disabled:N,onClick:()=>void S(),children:N?"Löscht ...":`Löschen (${v.size})`})]})]})})]})})}const ie="flex min-h-0 min-w-0 flex-1 flex-col",mt="inline-flex w-header min-h-header items-center justify-center border-r border-border text-primary transition-colors duration-100 not-disabled:cursor-pointer hover:not-disabled:bg-accent focus-visible:outline-2 focus-visible:outline-ring/60 focus-visible:-outline-offset-3 aria-expanded:bg-primary aria-expanded:text-primary-foreground aria-pressed:bg-primary aria-pressed:text-primary-foreground disabled:opacity-45";function xt(){var re;const n=Be(),r=_e((re=n.user)==null?void 0:re.id),a=n.can("runs.read"),u=a&&n.can("runs.write"),i=n.can("runs.inspect"),h=a&&n.can("runs.delete"),x=Fe(),m=t.useRef(null),l=t.useRef(null),[o,p]=t.useState(null),[j,C]=t.useState(null),[c,v]=t.useState(null),[g,O]=t.useState(null),[y,N]=t.useState(null),[B,_]=t.useState([]),[w,E]=t.useState(),[S,f]=t.useState(),[z,H]=t.useState(),[U,X]=t.useState(!1),[K,T]=t.useState(!1),[A,J]=t.useState(!1),[Y,D]=t.useState(),[me,xe]=t.useState(!1),[pe,ve]=t.useState(()=>new Set),[be,Z]=t.useState(!1),I=t.useRef(void 0),q=t.useRef(!1),P=t.useCallback(()=>{if(!a)return Promise.resolve();if(I.current)return q.current=!0,I.current;const s=async()=>{do{q.current=!1;try{_(await Ye()),Z(!1)}catch{Z(!0)}}while(q.current)};return I.current=s().finally(()=>{I.current=void 0}),I.current},[a]);t.useEffect(()=>{if(!a||w)return;P();const s=Ue.subscribe(Ke.channels.runs,{},()=>void P()),d=setInterval(()=>void P(),5e3);return()=>{s(),clearInterval(d)}},[w,a,P]);const L=t.useCallback((s=!1)=>{var d;J(!1),s&&((d=m.current)==null||d.focus({preventScroll:!0}))},[]),W=t.useCallback(()=>{D(void 0),xe(!0),J(!0)},[]),$=t.useCallback(()=>{A?L(!0):W()},[L,W,A]);t.useEffect(()=>{const s=d=>{if(d.defaultPrevented||d.repeat||d.altKey||d.shiftKey||d.key.toLowerCase()!=="i"||d.metaKey===d.ctrlKey)return;const R=m.current;!R||R.closest("[inert]")||(d.preventDefault(),$())};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[$]);const ee=t.useCallback((s,d)=>ve(R=>{if(R.has(s)===d)return R;const M=new Set(R);return d?M.add(s):M.delete(s),M}),[]),te=B,ge=te.find(s=>s.id===S),we=t.useCallback(()=>{D(void 0),X(!0)},[]),je=t.useCallback(()=>T(!1),[]),ye=t.useCallback(()=>{X(!1),requestAnimationFrame(()=>{var s;return(s=l.current)==null?void 0:s.focus()})},[]),Se=e.jsx(b,{"aria-label":"Einstellungen öffnen",onClick:we,ref:l,size:"icon-lg",title:"Einstellungen",variant:"ghost",children:e.jsx(Ze,{})}),ke=s=>{f(s),L(!0)},Ce=()=>{D(void 0),L(!0),E({id:crypto.randomUUID(),title:"Neuer Run",updatedAt:Date.now()})},Re=async s=>{const d=await Promise.allSettled(s.map(F=>et(F))),R=s.filter((F,Ae)=>d[Ae].status==="fulfilled");S!==void 0&&R.includes(S)&&f(void 0),await P();const M=d.find(F=>F.status==="rejected");if(M)throw M.reason};if(x.status==="loading")return e.jsx("div",{className:"m-auto p-6 text-muted-foreground",children:"Profil wird geladen."});if(x.status==="failed")return e.jsx("div",{className:"flex h-full",children:e.jsx("main",{className:"relative z-1 flex min-h-0 min-w-0 flex-1 bg-[image:var(--surface-backdrop)]",children:e.jsxs("div",{className:ie,children:[e.jsx("header",{className:"flex min-h-[42px] flex-none items-center gap-3 border-b border-border-soft pr-0.5 pb-2 pl-2.5",children:e.jsx("div",{className:"flex min-w-0 flex-1 items-center gap-3 text-[0.82rem] font-semibold text-foreground",children:"Profil nicht verfügbar"})}),e.jsxs(Te,{className:"m-auto max-w-[560px] gap-3 p-6",variant:"destructive",children:[e.jsx("p",{children:x.error}),e.jsx(b,{variant:"outline",onClick:()=>window.location.reload(),children:"Neu laden"})]})]})})});const k=x.registry,se=k.overviewPanels.filter(s=>s.readRight===void 0||n.can(s.readRight)),Q=se.filter(s=>s.placement!=="toolbar"),Ne=se.filter(s=>s.placement==="toolbar"),Ee=a||Q.length>0,ne=Q.some(s=>pe.has(s.id)),ze=qe(a?S:void 0,A,z);return e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("header",{className:"relative z-[80] flex h-header flex-none items-stretch border-b border-border bg-shell shadow-bar",children:[Ee&&e.jsx("div",{className:"relative flex flex-none self-stretch",children:e.jsx("button",{"aria-controls":"app-overview","aria-expanded":A,"aria-haspopup":"dialog","aria-keyshortcuts":"Meta+I Control+I","aria-label":A?"Übersicht schließen":"Übersicht öffnen",className:mt,onClick:$,ref:m,title:`Übersicht (Cmd+I / Ctrl+I)${ne?": Bearbeitung läuft":""}`,type:"button",children:ne?e.jsx(We,{"aria-hidden":!0,className:"size-[18px]"}):e.jsx($e,{size:22})})}),Ne.map(({id:s,Panel:d})=>e.jsx(pt,{id:s,onBusy:ee,onClose:()=>D(void 0),onOpen:()=>{!U&&!K&&!w&&(L(),D(s))},open:Y===s,Panel:d,registry:k,userLocation:ze},s)),e.jsx("div",{"aria-label":"Run-Titelleiste",className:"flex min-w-0 flex-1 items-stretch overflow-x-auto no-scrollbar focus-visible:outline-2 focus-visible:outline-ring/60 focus-visible:-outline-offset-3 max-md:in-[header:has([data-slot=overseer-toolbar][data-open=true])]:flex-[0_1_0]",ref:p,role:"region",tabIndex:0}),e.jsx(Qe,{}),e.jsxs("div",{className:"flex min-w-0 flex-[0_1_auto] items-stretch bg-shell has-data-[workspace-state=expanded]:w-[var(--workspace-panel-width,560px)] has-data-[workspace-state=expanded]:border-l has-data-[workspace-state=expanded]:border-border",children:[e.jsx("div",{className:"flex min-w-0 flex-1 empty:hidden",ref:C}),e.jsxs("div",{className:"flex flex-none items-center gap-1.5 px-2 max-md:gap-0.5 max-md:px-1",children:[n.can("settings.read")&&Se,i&&e.jsx(b,{"aria-haspopup":"dialog","aria-label":"Hilfe öffnen",onClick:()=>{D(void 0),T(!0)},size:"icon-lg",title:"Hilfe",variant:"ghost",children:e.jsx(lt,{})})]})]})]}),e.jsx(Ve,{failures:x.failures}),e.jsx(Ge.Provider,{value:g,children:e.jsx("div",{className:"relative flex min-h-0 flex-1 flex-col",ref:O,children:e.jsxs(Xe.Provider,{value:y,children:[e.jsxs("div",{className:"relative flex h-auto min-h-0 flex-1",ref:N,children:[e.jsx("main",{className:"relative z-1 flex min-h-0 min-w-0 flex-1 bg-[image:var(--surface-backdrop)] @container/chat-content",children:a&&S?e.jsx(ae,{headerContainer:o,workspaceHeaderContainer:j,statusContainer:c,onLocationChange:H,onViewed:r.markViewed,viewing:!A&&!U&&!K&&!w&&!Y,registry:k,session:ge??{id:S,title:"Neuer Run",updatedAt:Date.now()}},S):e.jsx("div",{className:ie,children:e.jsx("div",{className:"m-auto text-center text-muted-foreground",children:a?u?"Öffne oben links die Übersicht, um einen Run zu wählen oder einen neuen zu starten.":"Öffne oben links die Übersicht, um einen Run zu wählen. Du hast Lesezugriff.":"Für dieses Benutzerkonto sind keine Runs freigegeben."})})}),me&&e.jsx(ut,{onOpen:W,onBusy:ee,onClose:()=>L(!0),open:A,panels:Q,registry:k,runs:a?{activeId:S,canCreate:u&&(n.can("runs.create")||k.scriptEntries.some(s=>V(n,s.id))),canDelete:h,onCreate:Ce,onDelete:Re,onOpen:ke,registry:k,sessions:te,seenRevisions:r.revisions,unreachable:be}:void 0}),w&&e.jsx(ae,{onStarted:()=>{f(w.id),E(void 0),P()},registry:k,session:w,startDialog:{onClose:()=>E(void 0),initialEntryId:w.startEntryId}},w.id),U&&e.jsx(Je,{onClose:ye,registry:k}),i&&K&&e.jsx(ct,{onClose:je,sampleEntries:k.scriptEntries.filter(s=>V(n,s.id)).map(s=>s.id),onStartSample:s=>{!V(n,s)||!k.scriptEntries.some(d=>d.id===s)||(T(!1),D(void 0),L(),E({id:crypto.randomUUID(),title:"Neuer Run",updatedAt:Date.now(),startEntryId:s}))}})]}),e.jsx("footer",{"aria-label":"Run-Statusleiste",className:"relative flex h-statusbar w-full flex-none items-stretch pl-3 before:pointer-events-none before:absolute before:inset-0 before:z-[2] before:border-t before:border-border before:bg-shell before:shadow-status before:backdrop-blur-[16px] before:content-['']",ref:v})]})})})]})}function pt({id:n,onBusy:r,Panel:a,...u}){const i=t.useCallback(h=>r(n,h),[n,r]);return t.useEffect(()=>()=>r(n,!1),[n,r]),e.jsx(a,{...u,onBusy:i})}tt();const he=document.getElementById("root");if(!he)throw new Error("Root-Element fehlt");const le=st.createRoot(he);try{const n=nt(window);le.render(e.jsx(t.StrictMode,{children:e.jsx(rt,{children:e.jsx(at,{children:e.jsx(xt,{})})})}))}catch(n){le.render(e.jsxs(it,{children:[e.jsx("h1",{className:"my-3 text-[1.5rem]",children:"Darstellung konnte nicht geladen werden"}),e.jsx("p",{className:"mb-6 leading-normal",role:"alert",children:n instanceof Error?n.message:String(n)}),e.jsx(b,{onClick:()=>window.location.reload(),variant:"outline",children:"Erneut laden"})]}))}