@tyvm/knowhow 0.0.108 → 0.0.109-dev.05fe5a0

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 (210) hide show
  1. package/README.md +45 -0
  2. package/package.json +9 -4
  3. package/scripts/build-for-node.sh +10 -24
  4. package/scripts/publish.sh +86 -0
  5. package/src/agents/base/base.ts +10 -0
  6. package/src/agents/tools/execCommand.ts +49 -6
  7. package/src/agents/tools/index.ts +0 -1
  8. package/src/agents/tools/list.ts +0 -2
  9. package/src/chat/CliChatService.ts +10 -1
  10. package/src/chat/modules/AgentModule.ts +61 -31
  11. package/src/chat/modules/SessionsModule.ts +47 -3
  12. package/src/chat/renderer/CompactRenderer.ts +20 -0
  13. package/src/chat/renderer/ConsoleRenderer.ts +19 -0
  14. package/src/chat/renderer/FancyRenderer.ts +19 -0
  15. package/src/chat/renderer/types.ts +11 -0
  16. package/src/cli.ts +91 -659
  17. package/src/clients/anthropic.ts +17 -16
  18. package/src/clients/index.ts +6 -5
  19. package/src/clients/types.ts +19 -4
  20. package/src/cloudWorker.ts +175 -113
  21. package/src/commands/agent.ts +246 -0
  22. package/src/commands/misc.ts +174 -0
  23. package/src/commands/modules.ts +217 -0
  24. package/src/commands/services.ts +77 -0
  25. package/src/commands/workers.ts +168 -0
  26. package/src/config.ts +37 -0
  27. package/src/fileSync.ts +50 -17
  28. package/src/index.ts +18 -0
  29. package/src/logger.ts +197 -0
  30. package/src/plugins/embedding.ts +11 -6
  31. package/src/plugins/plugins.ts +0 -21
  32. package/src/plugins/vim.ts +5 -16
  33. package/src/processors/JsonCompressor.ts +6 -6
  34. package/src/services/EventService.ts +61 -1
  35. package/src/services/KnowhowClient.ts +34 -4
  36. package/src/services/modules/index.ts +95 -51
  37. package/src/services/modules/types.ts +6 -0
  38. package/src/tunnel.ts +216 -0
  39. package/src/types.ts +0 -1
  40. package/src/worker.ts +105 -312
  41. package/src/workers/auth/WsMiddleware.ts +99 -0
  42. package/src/workers/auth/authMiddleware.ts +104 -0
  43. package/src/workers/auth/types.ts +14 -2
  44. package/src/workers/tools/index.ts +2 -0
  45. package/src/workers/tools/reloadConfig.ts +84 -0
  46. package/tests/services/WorkerReloadConfig.test.ts +141 -0
  47. package/tests/unit/commands/github-credentials.test.ts +211 -0
  48. package/tests/unit/modules/moduleLoading.test.ts +39 -37
  49. package/tests/unit/plugins/pluginLoading.test.ts +0 -85
  50. package/ts_build/package.json +9 -4
  51. package/ts_build/src/agents/base/base.js +11 -0
  52. package/ts_build/src/agents/base/base.js.map +1 -1
  53. package/ts_build/src/agents/tools/execCommand.d.ts +1 -1
  54. package/ts_build/src/agents/tools/execCommand.js +39 -5
  55. package/ts_build/src/agents/tools/execCommand.js.map +1 -1
  56. package/ts_build/src/agents/tools/index.d.ts +0 -1
  57. package/ts_build/src/agents/tools/index.js +0 -1
  58. package/ts_build/src/agents/tools/index.js.map +1 -1
  59. package/ts_build/src/agents/tools/list.js +0 -2
  60. package/ts_build/src/agents/tools/list.js.map +1 -1
  61. package/ts_build/src/chat/CliChatService.js +13 -1
  62. package/ts_build/src/chat/CliChatService.js.map +1 -1
  63. package/ts_build/src/chat/modules/AgentModule.d.ts +1 -1
  64. package/ts_build/src/chat/modules/AgentModule.js +43 -20
  65. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  66. package/ts_build/src/chat/modules/SessionsModule.js +37 -3
  67. package/ts_build/src/chat/modules/SessionsModule.js.map +1 -1
  68. package/ts_build/src/chat/renderer/CompactRenderer.d.ts +4 -0
  69. package/ts_build/src/chat/renderer/CompactRenderer.js +16 -0
  70. package/ts_build/src/chat/renderer/CompactRenderer.js.map +1 -1
  71. package/ts_build/src/chat/renderer/ConsoleRenderer.d.ts +4 -0
  72. package/ts_build/src/chat/renderer/ConsoleRenderer.js +16 -0
  73. package/ts_build/src/chat/renderer/ConsoleRenderer.js.map +1 -1
  74. package/ts_build/src/chat/renderer/FancyRenderer.d.ts +4 -0
  75. package/ts_build/src/chat/renderer/FancyRenderer.js +16 -0
  76. package/ts_build/src/chat/renderer/FancyRenderer.js.map +1 -1
  77. package/ts_build/src/chat/renderer/types.d.ts +2 -0
  78. package/ts_build/src/cli.js +47 -519
  79. package/ts_build/src/cli.js.map +1 -1
  80. package/ts_build/src/clients/anthropic.d.ts +5 -5
  81. package/ts_build/src/clients/anthropic.js +17 -16
  82. package/ts_build/src/clients/anthropic.js.map +1 -1
  83. package/ts_build/src/clients/index.js +2 -4
  84. package/ts_build/src/clients/index.js.map +1 -1
  85. package/ts_build/src/clients/types.d.ts +3 -2
  86. package/ts_build/src/cloudWorker.d.ts +14 -0
  87. package/ts_build/src/cloudWorker.js +105 -66
  88. package/ts_build/src/cloudWorker.js.map +1 -1
  89. package/ts_build/src/commands/agent.d.ts +6 -0
  90. package/ts_build/src/commands/agent.js +229 -0
  91. package/ts_build/src/commands/agent.js.map +1 -0
  92. package/ts_build/src/commands/misc.d.ts +10 -0
  93. package/ts_build/src/commands/misc.js +197 -0
  94. package/ts_build/src/commands/misc.js.map +1 -0
  95. package/ts_build/src/commands/modules.d.ts +3 -0
  96. package/ts_build/src/commands/modules.js +207 -0
  97. package/ts_build/src/commands/modules.js.map +1 -0
  98. package/ts_build/src/commands/services.d.ts +5 -0
  99. package/ts_build/src/commands/services.js +87 -0
  100. package/ts_build/src/commands/services.js.map +1 -0
  101. package/ts_build/src/commands/workers.d.ts +6 -0
  102. package/ts_build/src/commands/workers.js +168 -0
  103. package/ts_build/src/commands/workers.js.map +1 -0
  104. package/ts_build/src/config.d.ts +1 -0
  105. package/ts_build/src/config.js +32 -0
  106. package/ts_build/src/config.js.map +1 -1
  107. package/ts_build/src/fileSync.d.ts +6 -0
  108. package/ts_build/src/fileSync.js +37 -12
  109. package/ts_build/src/fileSync.js.map +1 -1
  110. package/ts_build/src/index.d.ts +1 -0
  111. package/ts_build/src/index.js +17 -1
  112. package/ts_build/src/index.js.map +1 -1
  113. package/ts_build/src/logger.d.ts +21 -0
  114. package/ts_build/src/logger.js +106 -0
  115. package/ts_build/src/logger.js.map +1 -0
  116. package/ts_build/src/plugins/embedding.js +4 -3
  117. package/ts_build/src/plugins/embedding.js.map +1 -1
  118. package/ts_build/src/plugins/plugins.d.ts +0 -2
  119. package/ts_build/src/plugins/plugins.js +0 -11
  120. package/ts_build/src/plugins/plugins.js.map +1 -1
  121. package/ts_build/src/plugins/vim.js +3 -9
  122. package/ts_build/src/plugins/vim.js.map +1 -1
  123. package/ts_build/src/processors/JsonCompressor.js +4 -4
  124. package/ts_build/src/processors/JsonCompressor.js.map +1 -1
  125. package/ts_build/src/services/EventService.d.ts +6 -1
  126. package/ts_build/src/services/EventService.js +29 -0
  127. package/ts_build/src/services/EventService.js.map +1 -1
  128. package/ts_build/src/services/KnowhowClient.d.ts +13 -1
  129. package/ts_build/src/services/KnowhowClient.js +19 -2
  130. package/ts_build/src/services/KnowhowClient.js.map +1 -1
  131. package/ts_build/src/services/modules/index.d.ts +33 -0
  132. package/ts_build/src/services/modules/index.js +67 -47
  133. package/ts_build/src/services/modules/index.js.map +1 -1
  134. package/ts_build/src/services/modules/types.d.ts +6 -0
  135. package/ts_build/src/tunnel.d.ts +27 -0
  136. package/ts_build/src/tunnel.js +112 -0
  137. package/ts_build/src/tunnel.js.map +1 -0
  138. package/ts_build/src/types.d.ts +0 -1
  139. package/ts_build/src/types.js.map +1 -1
  140. package/ts_build/src/worker.d.ts +1 -4
  141. package/ts_build/src/worker.js +59 -227
  142. package/ts_build/src/worker.js.map +1 -1
  143. package/ts_build/src/workers/auth/WsMiddleware.d.ts +8 -0
  144. package/ts_build/src/workers/auth/WsMiddleware.js +65 -0
  145. package/ts_build/src/workers/auth/WsMiddleware.js.map +1 -0
  146. package/ts_build/src/workers/auth/authMiddleware.d.ts +3 -0
  147. package/ts_build/src/workers/auth/authMiddleware.js +60 -0
  148. package/ts_build/src/workers/auth/authMiddleware.js.map +1 -0
  149. package/ts_build/src/workers/auth/types.d.ts +8 -1
  150. package/ts_build/src/workers/tools/index.d.ts +2 -0
  151. package/ts_build/src/workers/tools/index.js +4 -1
  152. package/ts_build/src/workers/tools/index.js.map +1 -1
  153. package/ts_build/src/workers/tools/reloadConfig.d.ts +14 -0
  154. package/ts_build/src/workers/tools/reloadConfig.js +48 -0
  155. package/ts_build/src/workers/tools/reloadConfig.js.map +1 -0
  156. package/ts_build/tests/services/WorkerReloadConfig.test.d.ts +1 -0
  157. package/ts_build/tests/services/WorkerReloadConfig.test.js +86 -0
  158. package/ts_build/tests/services/WorkerReloadConfig.test.js.map +1 -0
  159. package/ts_build/tests/unit/commands/github-credentials.test.d.ts +1 -0
  160. package/ts_build/tests/unit/commands/github-credentials.test.js +146 -0
  161. package/ts_build/tests/unit/commands/github-credentials.test.js.map +1 -0
  162. package/ts_build/tests/unit/modules/moduleLoading.test.js +20 -26
  163. package/ts_build/tests/unit/modules/moduleLoading.test.js.map +1 -1
  164. package/ts_build/tests/unit/plugins/pluginLoading.test.js +0 -65
  165. package/ts_build/tests/unit/plugins/pluginLoading.test.js.map +1 -1
  166. package/src/agents/tools/executeScript/README.md +0 -94
  167. package/src/agents/tools/executeScript/definition.ts +0 -79
  168. package/src/agents/tools/executeScript/examples/dependency-injection-validation.ts +0 -272
  169. package/src/agents/tools/executeScript/examples/quick-test.ts +0 -74
  170. package/src/agents/tools/executeScript/examples/serialization-test.ts +0 -321
  171. package/src/agents/tools/executeScript/examples/test-runner.ts +0 -197
  172. package/src/agents/tools/executeScript/index.ts +0 -98
  173. package/src/services/script-execution/SandboxContext.ts +0 -282
  174. package/src/services/script-execution/ScriptExecutor.ts +0 -441
  175. package/src/services/script-execution/ScriptPolicy.ts +0 -194
  176. package/src/services/script-execution/ScriptTracer.ts +0 -249
  177. package/src/services/script-execution/types.ts +0 -134
  178. package/ts_build/src/agents/tools/executeScript/definition.d.ts +0 -2
  179. package/ts_build/src/agents/tools/executeScript/definition.js +0 -76
  180. package/ts_build/src/agents/tools/executeScript/definition.js.map +0 -1
  181. package/ts_build/src/agents/tools/executeScript/examples/dependency-injection-validation.d.ts +0 -18
  182. package/ts_build/src/agents/tools/executeScript/examples/dependency-injection-validation.js +0 -192
  183. package/ts_build/src/agents/tools/executeScript/examples/dependency-injection-validation.js.map +0 -1
  184. package/ts_build/src/agents/tools/executeScript/examples/quick-test.d.ts +0 -3
  185. package/ts_build/src/agents/tools/executeScript/examples/quick-test.js +0 -64
  186. package/ts_build/src/agents/tools/executeScript/examples/quick-test.js.map +0 -1
  187. package/ts_build/src/agents/tools/executeScript/examples/serialization-test.d.ts +0 -15
  188. package/ts_build/src/agents/tools/executeScript/examples/serialization-test.js +0 -266
  189. package/ts_build/src/agents/tools/executeScript/examples/serialization-test.js.map +0 -1
  190. package/ts_build/src/agents/tools/executeScript/examples/test-runner.d.ts +0 -4
  191. package/ts_build/src/agents/tools/executeScript/examples/test-runner.js +0 -208
  192. package/ts_build/src/agents/tools/executeScript/examples/test-runner.js.map +0 -1
  193. package/ts_build/src/agents/tools/executeScript/index.d.ts +0 -28
  194. package/ts_build/src/agents/tools/executeScript/index.js +0 -72
  195. package/ts_build/src/agents/tools/executeScript/index.js.map +0 -1
  196. package/ts_build/src/services/script-execution/SandboxContext.d.ts +0 -34
  197. package/ts_build/src/services/script-execution/SandboxContext.js +0 -189
  198. package/ts_build/src/services/script-execution/SandboxContext.js.map +0 -1
  199. package/ts_build/src/services/script-execution/ScriptExecutor.d.ts +0 -19
  200. package/ts_build/src/services/script-execution/ScriptExecutor.js +0 -269
  201. package/ts_build/src/services/script-execution/ScriptExecutor.js.map +0 -1
  202. package/ts_build/src/services/script-execution/ScriptPolicy.d.ts +0 -28
  203. package/ts_build/src/services/script-execution/ScriptPolicy.js +0 -115
  204. package/ts_build/src/services/script-execution/ScriptPolicy.js.map +0 -1
  205. package/ts_build/src/services/script-execution/ScriptTracer.d.ts +0 -19
  206. package/ts_build/src/services/script-execution/ScriptTracer.js +0 -186
  207. package/ts_build/src/services/script-execution/ScriptTracer.js.map +0 -1
  208. package/ts_build/src/services/script-execution/types.d.ts +0 -108
  209. package/ts_build/src/services/script-execution/types.js +0 -3
  210. package/ts_build/src/services/script-execution/types.js.map +0 -1
package/src/tunnel.ts ADDED
@@ -0,0 +1,216 @@
1
+ import os from "os";
2
+ import { WebSocket } from "ws";
3
+ import { createTunnelHandler, TunnelHandler } from "@tyvm/knowhow-tunnel";
4
+ import { loadJwt } from "./login";
5
+ import { wait } from "./utils";
6
+ import { getConfig } from "./config";
7
+ import { KNOWHOW_API_URL } from "./services/KnowhowClient";
8
+ import { ModulesService } from "./services/modules";
9
+ import { WorkerPasskeyAuthService } from "./workers/auth/WorkerPasskeyAuth";
10
+ import { WsMiddlewareStack } from "./workers/auth/WsMiddleware";
11
+ import { makeAuthMiddleware } from "./workers/auth/authMiddleware";
12
+
13
+ /**
14
+ * Extract the tunnel domain and protocol from the API URL.
15
+ * e.g., "https://api.knowhow.tyvm.ai" -> { domain: "worker.knowhow.tyvm.ai", useHttps: true }
16
+ * e.g., "http://localhost:4000" -> { domain: "worker.localhost:4000", useHttps: false }
17
+ */
18
+ export function extractTunnelDomain(apiUrl: string): {
19
+ domain: string;
20
+ useHttps: boolean;
21
+ } {
22
+ try {
23
+ const url = new URL(apiUrl);
24
+ const useHttps = url.protocol === "https:";
25
+
26
+ // For localhost, include port; for production, just use hostname
27
+ if (url.hostname === "localhost" || url.hostname === "127.0.0.1") {
28
+ return {
29
+ domain: `worker.${url.hostname}:${url.port || "80"}`,
30
+ useHttps,
31
+ };
32
+ }
33
+ return { domain: `worker.${url.hostname}`, useHttps };
34
+ } catch (err) {
35
+ console.error("Failed to parse API_URL for tunnel domain:", err);
36
+ return { domain: "worker.localhost:4000", useHttps: false }; // fallback
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Initialize a tunnel handler and load tunnel modules.
42
+ */
43
+ export async function initTunnelHandler(
44
+ tunnelConnection: WebSocket,
45
+ tunnelConfig: Parameters<typeof createTunnelHandler>[1]
46
+ ): Promise<TunnelHandler> {
47
+ const handler = createTunnelHandler(tunnelConnection, tunnelConfig);
48
+ console.log("🌐 Tunnel handler initialized");
49
+ console.log(tunnelConfig);
50
+
51
+ const tunnelModuleService = new ModulesService();
52
+ const tunnelContext = await tunnelModuleService.overrideDefaultContext({
53
+ Tunnel: handler,
54
+ });
55
+ tunnelModuleService.loadModulesFromConfig(tunnelContext).catch((err) => {
56
+ console.error("Failed to load tunnel modules:", err);
57
+ });
58
+
59
+ return handler;
60
+ }
61
+
62
+ /**
63
+ * Resolve tunnel local host, log port mapping, and return shared tunnel setup values.
64
+ * Extracted to avoid duplication between worker() and tunnel().
65
+ */
66
+ export function resolveTunnelConfig(
67
+ config: Awaited<ReturnType<typeof getConfig>>,
68
+ isInsideDocker: boolean
69
+ ): { tunnelLocalHost: string; portMapping: Record<string, number> } {
70
+ // Determine localHost based on environment
71
+ let tunnelLocalHost = config.worker?.tunnel?.localHost;
72
+ if (!tunnelLocalHost) {
73
+ if (isInsideDocker) {
74
+ tunnelLocalHost = "host.docker.internal";
75
+ console.log(
76
+ "🐳 Docker detected: tunnel will use host.docker.internal to reach host services"
77
+ );
78
+ } else {
79
+ tunnelLocalHost = "127.0.0.1";
80
+ }
81
+ }
82
+
83
+ // Check for port mapping configuration
84
+ const portMapping = (config.worker?.tunnel?.portMapping || {}) as Record<string, number>;
85
+ if (Object.keys(portMapping).length > 0) {
86
+ console.log("🔀 Port mapping configured:");
87
+ for (const [containerPort, hostPort] of Object.entries(portMapping)) {
88
+ console.log(` Container port ${containerPort} → Host port ${hostPort}`);
89
+ }
90
+ }
91
+
92
+ return { tunnelLocalHost, portMapping };
93
+ }
94
+
95
+ /**
96
+ * Options for connectTunnelWebSocket helper.
97
+ */
98
+ export interface TunnelWebSocketOptions {
99
+ /** Already-resolved tunnel domain (hostname only, no protocol) */
100
+ tunnelDomain: string;
101
+ /** Whether the tunnel should use HTTPS */
102
+ tunnelUseHttps: boolean;
103
+ /** Local host to forward tunnel traffic to */
104
+ tunnelLocalHost: string;
105
+ /** Port mapping configuration */
106
+ portMapping: Record<string, number>;
107
+ /** Worker config (for tunnel sub-config) */
108
+ config: Awaited<ReturnType<typeof getConfig>>;
109
+ /** HTTP headers to attach to the WebSocket upgrade request */
110
+ headers: Record<string, string>;
111
+ /** Callback invoked with the TunnelHandler once the connection opens */
112
+ onOpen?: (handler: TunnelHandler) => void;
113
+ /** Called when the connection closes; receives code + reason string */
114
+ onClose?: (code: number, reason: string) => void;
115
+ /** Called on error */
116
+ onError?: (error: Error) => void;
117
+ /** Optional passkey auth service — if provided, applies WS middleware to gate tunnel traffic */
118
+ authService?: WorkerPasskeyAuthService | null;
119
+ }
120
+
121
+ /**
122
+ * Create a tunnel WebSocket connection, build the tunnelConfig, and
123
+ * initialize the tunnel handler. Returns the WebSocket.
124
+ *
125
+ * The caller is responsible for storing a reference to the returned TunnelHandler
126
+ * (via onOpen) and performing any outer-state cleanup (via onClose / onError).
127
+ */
128
+ export function connectTunnelWebSocket(
129
+ options: TunnelWebSocketOptions
130
+ ): WebSocket {
131
+ const {
132
+ tunnelDomain,
133
+ tunnelUseHttps,
134
+ tunnelLocalHost,
135
+ portMapping,
136
+ config,
137
+ headers,
138
+ onOpen,
139
+ onClose,
140
+ onError,
141
+ authService,
142
+ } = options;
143
+
144
+ const tunnelConnection = new WebSocket(`${KNOWHOW_API_URL}/ws/tunnel`, { headers });
145
+
146
+ tunnelConnection.on("open", async () => {
147
+ console.log("Tunnel WebSocket connected");
148
+
149
+ // Apply passkey auth middleware FIRST, before tunnel handler registers its
150
+ // "message" listener. Node.js EventEmitter fires listeners in registration
151
+ // order, so our middleware runs first. wrapSocket() also redirects future
152
+ // ws.on("message", ...) calls to an inner emitter, ensuring the tunnel
153
+ // handler only receives messages that passed the middleware.
154
+ if (authService) {
155
+ const stack = new WsMiddlewareStack();
156
+ stack.use(makeAuthMiddleware(authService));
157
+ stack.wrapSocket(tunnelConnection);
158
+ }
159
+
160
+ const allowedPorts = config.worker?.tunnel?.allowedPorts || [];
161
+
162
+ // Create URL rewriter callback that returns the hostname (without protocol).
163
+ // The tunnel package will add the protocol based on the useHttps config.
164
+ const urlRewriter = (port: number, metadata?: any) => {
165
+ const workerId = metadata?.workerId;
166
+ const secret = metadata?.secret;
167
+ // Examples: secret-p3000.worker.example.com / workerId-p3000.worker.example.com
168
+ const subdomain = secret
169
+ ? `${secret}-p${port}`
170
+ : `${workerId}-p${port}`;
171
+ return `${subdomain}.${tunnelDomain}`;
172
+ };
173
+
174
+ const tunnelConfig = {
175
+ allowedPorts,
176
+ maxConcurrentStreams: config.worker?.tunnel?.maxConcurrentStreams || 50,
177
+ tunnelUseHttps,
178
+ localHost: tunnelLocalHost,
179
+ urlRewriter,
180
+ enableUrlRewriting: config.worker?.tunnel?.enableUrlRewriting !== false,
181
+ portMapping,
182
+ logLevel: "debug" as const,
183
+ };
184
+
185
+ const handler = await initTunnelHandler(tunnelConnection, tunnelConfig);
186
+ onOpen?.(handler);
187
+ });
188
+
189
+ tunnelConnection.on("close", (code, reason) => {
190
+ console.log(
191
+ `Tunnel WebSocket closed. Code: ${code}, Reason: ${reason.toString()}`
192
+ );
193
+ onClose?.(code, reason.toString());
194
+ });
195
+
196
+ tunnelConnection.on("error", (error) => {
197
+ console.error("Tunnel WebSocket error:", error);
198
+ onError?.(error);
199
+ });
200
+
201
+ return tunnelConnection;
202
+ }
203
+
204
+ /**
205
+ * The minimal set of tool names that are always registered when running in
206
+ * tunnel mode. These are the tools the backend and frontend need to interact
207
+ * with the tunnel worker (port discovery, passkey auth).
208
+ *
209
+ * Additional tools can be added here in the future without changing the CLI.
210
+ */
211
+ export const TUNNEL_MINIMAL_TOOLS = [
212
+ "listAllowedPorts",
213
+ "unlock",
214
+ "lock",
215
+ "reloadConfig",
216
+ ];
package/src/types.ts CHANGED
@@ -52,7 +52,6 @@ export type Config = {
52
52
  modules?: string[];
53
53
  };
54
54
  modules: string[];
55
- pluginPackages?: Record<string, string>;
56
55
  agents: Assistant[];
57
56
  mcps: McpConfig[];
58
57
  modelProviders: ModelProvider[];