@dbx-tools/appkit-graphiti 0.6.113 → 0.6.114

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/README.md CHANGED
@@ -62,6 +62,9 @@ Plugin config overrides environment values:
62
62
  - `appPort` / `GRAPHITI_APP_PORT`: AppKit's internal port, default public + 1;
63
63
  - `graphitiPort` / `GRAPHITI_PORT`: Graphiti's internal port; a free loopback
64
64
  port is selected automatically when omitted;
65
+ - `litellmPort` / `LITELLM_PORT`: the managed LiteLLM port; a separate free
66
+ loopback port is selected automatically so another local proxy cannot be
67
+ mistaken for Graphiti's model backend;
65
68
  - `routePrefix` / `GRAPHITI_ROUTE_PREFIX`: public Graphiti prefix, default
66
69
  `/graphiti`;
67
70
  - `python` / `PYTHON`: Python executable, default `python3`;
@@ -8,6 +8,7 @@ export interface GraphitiPluginConfig extends BasePluginConfig {
8
8
  publicPort?: number;
9
9
  appPort?: number;
10
10
  graphitiPort?: number;
11
+ litellmPort?: number;
11
12
  routePrefix?: string;
12
13
  python?: string;
13
14
  journalNamespace?: string;
@@ -16,6 +17,7 @@ export interface ResolvedGraphitiPluginConfig extends GraphitiPluginConfig {
16
17
  publicPort: number;
17
18
  appPort: number;
18
19
  graphitiPort: number;
20
+ litellmPort: number;
19
21
  routePrefix: string;
20
22
  python: string;
21
23
  journalNamespace: string;
@@ -38,6 +40,11 @@ export declare const GRAPHITI_CONFIG_SCHEMA: {
38
40
  minimum: number;
39
41
  maximum: number;
40
42
  };
43
+ litellmPort: {
44
+ type: "integer";
45
+ minimum: number;
46
+ maximum: number;
47
+ };
41
48
  routePrefix: {
42
49
  type: "string";
43
50
  };
package/lib/src/config.js CHANGED
@@ -11,6 +11,7 @@ export const GRAPHITI_CONFIG_SCHEMA = {
11
11
  publicPort: { type: "integer", minimum: 1, maximum: 65535 },
12
12
  appPort: { type: "integer", minimum: 1, maximum: 65535 },
13
13
  graphitiPort: { type: "integer", minimum: 1, maximum: 65535 },
14
+ litellmPort: { type: "integer", minimum: 1, maximum: 65535 },
14
15
  routePrefix: { type: "string" },
15
16
  python: { type: "string" },
16
17
  journalNamespace: { type: "string" },
@@ -22,7 +23,9 @@ export function resolveGraphitiConfig(config = {}) {
22
23
  const publicPort = coreConfig.port(config.publicPort, "DATABRICKS_APP_PORT", 8000, coreConfig.ENV_ONLY);
23
24
  const appPort = coreConfig.port(config.appPort, "GRAPHITI_APP_PORT", publicPort + 1, coreConfig.ENV_ONLY);
24
25
  const graphitiPort = coreConfig.port(config.graphitiPort, "GRAPHITI_PORT", 0, coreConfig.ENV_ONLY);
25
- if (new Set([publicPort, appPort, graphitiPort]).size !== 3) {
26
+ const litellmPort = coreConfig.port(config.litellmPort, "LITELLM_PORT", 0, coreConfig.ENV_ONLY);
27
+ const configuredPorts = [publicPort, appPort, graphitiPort, litellmPort].filter(Boolean);
28
+ if (new Set(configuredPorts).size !== configuredPorts.length) {
26
29
  throw new ConfigurationError("Graphiti public, AppKit, and sidecar ports must be distinct");
27
30
  }
28
31
  const routePrefix = normalizeRoutePrefix(config.routePrefix ??
@@ -37,6 +40,7 @@ export function resolveGraphitiConfig(config = {}) {
37
40
  publicPort,
38
41
  appPort,
39
42
  graphitiPort,
43
+ litellmPort,
40
44
  routePrefix,
41
45
  python,
42
46
  journalNamespace,
@@ -53,4 +57,4 @@ function normalizeRoutePrefix(value) {
53
57
  }
54
58
  return normalized;
55
59
  }
56
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLGtCQUFrQixFQUF5QixNQUFNLG9CQUFvQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxNQUFNLElBQUksVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFxQnZELE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHO0lBQ3BDLElBQUksRUFBRSxRQUFRO0lBQ2QsVUFBVSxFQUFFO1FBQ1YsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUU7UUFDM0QsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUU7UUFDeEQsWUFBWSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUU7UUFDN0QsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtRQUMvQixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO1FBQzFCLGdCQUFnQixFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtLQUNyQztJQUNELG9CQUFvQixFQUFFLEtBQUs7Q0FDTixDQUFDO0FBRXhCLCtFQUErRTtBQUMvRSxNQUFNLFVBQVUscUJBQXFCLENBQ25DLFNBQStCLEVBQUU7SUFFakMsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FDaEMsTUFBTSxDQUFDLFVBQVUsRUFDakIscUJBQXFCLEVBQ3JCLElBQUksRUFDSixVQUFVLENBQUMsUUFBUSxDQUNwQixDQUFDO0lBQ0YsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FDN0IsTUFBTSxDQUFDLE9BQU8sRUFDZCxtQkFBbUIsRUFDbkIsVUFBVSxHQUFHLENBQUMsRUFDZCxVQUFVLENBQUMsUUFBUSxDQUNwQixDQUFDO0lBQ0YsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FDbEMsTUFBTSxDQUFDLFlBQVksRUFDbkIsZUFBZSxFQUNmLENBQUMsRUFDRCxVQUFVLENBQUMsUUFBUSxDQUNwQixDQUFDO0lBQ0YsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDNUQsTUFBTSxJQUFJLGtCQUFrQixDQUFDLDZEQUE2RCxDQUFDLENBQUM7SUFDOUYsQ0FBQztJQUNELE1BQU0sV0FBVyxHQUFHLG9CQUFvQixDQUN0QyxNQUFNLENBQUMsV0FBVztRQUNoQixVQUFVLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUM7UUFDN0QsV0FBVyxDQUNkLENBQUM7SUFDRixNQUFNLE1BQU0sR0FDVixNQUFNLENBQUMsTUFBTSxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxTQUFTLENBQUM7SUFDdkYsTUFBTSxnQkFBZ0IsR0FDcEIsTUFBTSxDQUFDLGdCQUFnQjtRQUN2QixVQUFVLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLEVBQUU7UUFDakUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLEVBQUU7UUFDdkMsU0FBUyxDQUFDO0lBQ1osT0FBTztRQUNMLFVBQVU7UUFDVixPQUFPO1FBQ1AsWUFBWTtRQUNaLFdBQVc7UUFDWCxNQUFNO1FBQ04sZ0JBQWdCO0tBQ2pCLENBQUM7QUFDSixDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLE1BQU0sVUFBVSxPQUFPLENBQUMsU0FBK0IsRUFBRTtJQUN2RCxPQUFPLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUMvQyxDQUFDO0FBRUQsU0FBUyxvQkFBb0IsQ0FBQyxLQUFhO0lBQ3pDLE1BQU0sVUFBVSxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUNoRSxJQUFJLFVBQVUsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksa0JBQWtCLENBQUMsa0RBQWtELENBQUMsQ0FBQztJQUNuRixDQUFDO0lBQ0QsT0FBTyxVQUFVLENBQUM7QUFDcEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXBwS2l0IEdyYXBoaXRpIHNpZGVjYXIgcG9ydHMsIHJvdXRlIHByZWZpeCwgYW5kIFB5dGhvbiBjb21tYW5kLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0IHsgQ29uZmlndXJhdGlvbkVycm9yLCB0eXBlIEJhc2VQbHVnaW5Db25maWcgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBjb25maWcgYXMgY29yZUNvbmZpZyB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB0eXBlIHsgSlNPTlNjaGVtYTcgfSBmcm9tIFwianNvbi1zY2hlbWFcIjtcblxuZXhwb3J0IGludGVyZmFjZSBHcmFwaGl0aVBsdWdpbkNvbmZpZyBleHRlbmRzIEJhc2VQbHVnaW5Db25maWcge1xuICBwdWJsaWNQb3J0PzogbnVtYmVyO1xuICBhcHBQb3J0PzogbnVtYmVyO1xuICBncmFwaGl0aVBvcnQ/OiBudW1iZXI7XG4gIHJvdXRlUHJlZml4Pzogc3RyaW5nO1xuICBweXRob24/OiBzdHJpbmc7XG4gIGpvdXJuYWxOYW1lc3BhY2U/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRHcmFwaGl0aVBsdWdpbkNvbmZpZyBleHRlbmRzIEdyYXBoaXRpUGx1Z2luQ29uZmlnIHtcbiAgcHVibGljUG9ydDogbnVtYmVyO1xuICBhcHBQb3J0OiBudW1iZXI7XG4gIGdyYXBoaXRpUG9ydDogbnVtYmVyO1xuICByb3V0ZVByZWZpeDogc3RyaW5nO1xuICBweXRob246IHN0cmluZztcbiAgam91cm5hbE5hbWVzcGFjZTogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgR1JBUEhJVElfQ09ORklHX1NDSEVNQSA9IHtcbiAgdHlwZTogXCJvYmplY3RcIixcbiAgcHJvcGVydGllczoge1xuICAgIHB1YmxpY1BvcnQ6IHsgdHlwZTogXCJpbnRlZ2VyXCIsIG1pbmltdW06IDEsIG1heGltdW06IDY1NTM1IH0sXG4gICAgYXBwUG9ydDogeyB0eXBlOiBcImludGVnZXJcIiwgbWluaW11bTogMSwgbWF4aW11bTogNjU1MzUgfSxcbiAgICBncmFwaGl0aVBvcnQ6IHsgdHlwZTogXCJpbnRlZ2VyXCIsIG1pbmltdW06IDEsIG1heGltdW06IDY1NTM1IH0sXG4gICAgcm91dGVQcmVmaXg6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgIHB5dGhvbjogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgam91cm5hbE5hbWVzcGFjZTogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gIH0sXG4gIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbn0gc2F0aXNmaWVzIEpTT05TY2hlbWE3O1xuXG4vKiogUmVzb2x2ZSBwbHVnaW4gY29uZmlnIG92ZXIgZXhhY3QgZW52aXJvbm1lbnQgdmFsdWVzIGFuZCBzdGFibGUgZGVmYXVsdHMuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUdyYXBoaXRpQ29uZmlnKFxuICBjb25maWc6IEdyYXBoaXRpUGx1Z2luQ29uZmlnID0ge30sXG4pOiBSZXNvbHZlZEdyYXBoaXRpUGx1Z2luQ29uZmlnIHtcbiAgY29uc3QgcHVibGljUG9ydCA9IGNvcmVDb25maWcucG9ydChcbiAgICBjb25maWcucHVibGljUG9ydCxcbiAgICBcIkRBVEFCUklDS1NfQVBQX1BPUlRcIixcbiAgICA4MDAwLFxuICAgIGNvcmVDb25maWcuRU5WX09OTFksXG4gICk7XG4gIGNvbnN0IGFwcFBvcnQgPSBjb3JlQ29uZmlnLnBvcnQoXG4gICAgY29uZmlnLmFwcFBvcnQsXG4gICAgXCJHUkFQSElUSV9BUFBfUE9SVFwiLFxuICAgIHB1YmxpY1BvcnQgKyAxLFxuICAgIGNvcmVDb25maWcuRU5WX09OTFksXG4gICk7XG4gIGNvbnN0IGdyYXBoaXRpUG9ydCA9IGNvcmVDb25maWcucG9ydChcbiAgICBjb25maWcuZ3JhcGhpdGlQb3J0LFxuICAgIFwiR1JBUEhJVElfUE9SVFwiLFxuICAgIDAsXG4gICAgY29yZUNvbmZpZy5FTlZfT05MWSxcbiAgKTtcbiAgaWYgKG5ldyBTZXQoW3B1YmxpY1BvcnQsIGFwcFBvcnQsIGdyYXBoaXRpUG9ydF0pLnNpemUgIT09IDMpIHtcbiAgICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKFwiR3JhcGhpdGkgcHVibGljLCBBcHBLaXQsIGFuZCBzaWRlY2FyIHBvcnRzIG11c3QgYmUgZGlzdGluY3RcIik7XG4gIH1cbiAgY29uc3Qgcm91dGVQcmVmaXggPSBub3JtYWxpemVSb3V0ZVByZWZpeChcbiAgICBjb25maWcucm91dGVQcmVmaXggPz9cbiAgICAgIGNvcmVDb25maWcudGV4dChcIkdSQVBISVRJX1JPVVRFX1BSRUZJWFwiLCBjb3JlQ29uZmlnLkVOVl9PTkxZKSA/P1xuICAgICAgXCIvZ3JhcGhpdGlcIixcbiAgKTtcbiAgY29uc3QgcHl0aG9uID1cbiAgICBjb25maWcucHl0aG9uID8/IGNvcmVDb25maWcudGV4dChcIlBZVEhPTlwiLCBjb3JlQ29uZmlnLkVOVl9PTkxZKT8udHJpbSgpID8/IFwicHl0aG9uM1wiO1xuICBjb25zdCBqb3VybmFsTmFtZXNwYWNlID1cbiAgICBjb25maWcuam91cm5hbE5hbWVzcGFjZSA/P1xuICAgIGNvcmVDb25maWcudGV4dChcIkpPVVJOQUxfTkFNRVNQQUNFXCIsIGNvcmVDb25maWcuRU5WX09OTFkpPy50cmltKCkgPz9cbiAgICBwcm9jZXNzLmVudi5EQVRBQlJJQ0tTX0FQUF9OQU1FPy50cmltKCkgPz9cbiAgICBcImRlZmF1bHRcIjtcbiAgcmV0dXJuIHtcbiAgICBwdWJsaWNQb3J0LFxuICAgIGFwcFBvcnQsXG4gICAgZ3JhcGhpdGlQb3J0LFxuICAgIHJvdXRlUHJlZml4LFxuICAgIHB5dGhvbixcbiAgICBqb3VybmFsTmFtZXNwYWNlLFxuICB9O1xufVxuXG4vKiogUmV0dXJuIHRoZSBpbnRlcm5hbCBwb3J0IGFuIEFwcEtpdCBgc2VydmVyKClgIHBsdWdpbiBzaG91bGQgYmluZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBQb3J0KGNvbmZpZzogR3JhcGhpdGlQbHVnaW5Db25maWcgPSB7fSk6IG51bWJlciB7XG4gIHJldHVybiByZXNvbHZlR3JhcGhpdGlDb25maWcoY29uZmlnKS5hcHBQb3J0O1xufVxuXG5mdW5jdGlvbiBub3JtYWxpemVSb3V0ZVByZWZpeCh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IGAvJHt2YWx1ZS50cmltKCkucmVwbGFjZSgvXlxcLyt8XFwvKyQvZywgXCJcIil9YDtcbiAgaWYgKG5vcm1hbGl6ZWQgPT09IFwiL1wiKSB7XG4gICAgdGhyb3cgbmV3IENvbmZpZ3VyYXRpb25FcnJvcihcIkdyYXBoaXRpIHJvdXRlUHJlZml4IG11c3QgY29udGFpbiBhIHBhdGggc2VnbWVudFwiKTtcbiAgfVxuICByZXR1cm4gbm9ybWFsaXplZDtcbn1cbiJdfQ==
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLGtCQUFrQixFQUF5QixNQUFNLG9CQUFvQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxNQUFNLElBQUksVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUF1QnZELE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHO0lBQ3BDLElBQUksRUFBRSxRQUFRO0lBQ2QsVUFBVSxFQUFFO1FBQ1YsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUU7UUFDM0QsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUU7UUFDeEQsWUFBWSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUU7UUFDN0QsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUU7UUFDNUQsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtRQUMvQixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO1FBQzFCLGdCQUFnQixFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtLQUNyQztJQUNELG9CQUFvQixFQUFFLEtBQUs7Q0FDTixDQUFDO0FBRXhCLCtFQUErRTtBQUMvRSxNQUFNLFVBQVUscUJBQXFCLENBQ25DLFNBQStCLEVBQUU7SUFFakMsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FDaEMsTUFBTSxDQUFDLFVBQVUsRUFDakIscUJBQXFCLEVBQ3JCLElBQUksRUFDSixVQUFVLENBQUMsUUFBUSxDQUNwQixDQUFDO0lBQ0YsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FDN0IsTUFBTSxDQUFDLE9BQU8sRUFDZCxtQkFBbUIsRUFDbkIsVUFBVSxHQUFHLENBQUMsRUFDZCxVQUFVLENBQUMsUUFBUSxDQUNwQixDQUFDO0lBQ0YsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FDbEMsTUFBTSxDQUFDLFlBQVksRUFDbkIsZUFBZSxFQUNmLENBQUMsRUFDRCxVQUFVLENBQUMsUUFBUSxDQUNwQixDQUFDO0lBQ0YsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLGNBQWMsRUFBRSxDQUFDLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2hHLE1BQU0sZUFBZSxHQUFHLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsV0FBVyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pGLElBQUksSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUMsSUFBSSxLQUFLLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM3RCxNQUFNLElBQUksa0JBQWtCLENBQUMsNkRBQTZELENBQUMsQ0FBQztJQUM5RixDQUFDO0lBQ0QsTUFBTSxXQUFXLEdBQUcsb0JBQW9CLENBQ3RDLE1BQU0sQ0FBQyxXQUFXO1FBQ2hCLFVBQVUsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztRQUM3RCxXQUFXLENBQ2QsQ0FBQztJQUNGLE1BQU0sTUFBTSxHQUNWLE1BQU0sQ0FBQyxNQUFNLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLFNBQVMsQ0FBQztJQUN2RixNQUFNLGdCQUFnQixHQUNwQixNQUFNLENBQUMsZ0JBQWdCO1FBQ3ZCLFVBQVUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRTtRQUNqRSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLElBQUksRUFBRTtRQUN2QyxTQUFTLENBQUM7SUFDWixPQUFPO1FBQ0wsVUFBVTtRQUNWLE9BQU87UUFDUCxZQUFZO1FBQ1osV0FBVztRQUNYLFdBQVc7UUFDWCxNQUFNO1FBQ04sZ0JBQWdCO0tBQ2pCLENBQUM7QUFDSixDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLE1BQU0sVUFBVSxPQUFPLENBQUMsU0FBK0IsRUFBRTtJQUN2RCxPQUFPLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUMvQyxDQUFDO0FBRUQsU0FBUyxvQkFBb0IsQ0FBQyxLQUFhO0lBQ3pDLE1BQU0sVUFBVSxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUNoRSxJQUFJLFVBQVUsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksa0JBQWtCLENBQUMsa0RBQWtELENBQUMsQ0FBQztJQUNuRixDQUFDO0lBQ0QsT0FBTyxVQUFVLENBQUM7QUFDcEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXBwS2l0IEdyYXBoaXRpIHNpZGVjYXIgcG9ydHMsIHJvdXRlIHByZWZpeCwgYW5kIFB5dGhvbiBjb21tYW5kLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0IHsgQ29uZmlndXJhdGlvbkVycm9yLCB0eXBlIEJhc2VQbHVnaW5Db25maWcgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBjb25maWcgYXMgY29yZUNvbmZpZyB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB0eXBlIHsgSlNPTlNjaGVtYTcgfSBmcm9tIFwianNvbi1zY2hlbWFcIjtcblxuZXhwb3J0IGludGVyZmFjZSBHcmFwaGl0aVBsdWdpbkNvbmZpZyBleHRlbmRzIEJhc2VQbHVnaW5Db25maWcge1xuICBwdWJsaWNQb3J0PzogbnVtYmVyO1xuICBhcHBQb3J0PzogbnVtYmVyO1xuICBncmFwaGl0aVBvcnQ/OiBudW1iZXI7XG4gIGxpdGVsbG1Qb3J0PzogbnVtYmVyO1xuICByb3V0ZVByZWZpeD86IHN0cmluZztcbiAgcHl0aG9uPzogc3RyaW5nO1xuICBqb3VybmFsTmFtZXNwYWNlPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkR3JhcGhpdGlQbHVnaW5Db25maWcgZXh0ZW5kcyBHcmFwaGl0aVBsdWdpbkNvbmZpZyB7XG4gIHB1YmxpY1BvcnQ6IG51bWJlcjtcbiAgYXBwUG9ydDogbnVtYmVyO1xuICBncmFwaGl0aVBvcnQ6IG51bWJlcjtcbiAgbGl0ZWxsbVBvcnQ6IG51bWJlcjtcbiAgcm91dGVQcmVmaXg6IHN0cmluZztcbiAgcHl0aG9uOiBzdHJpbmc7XG4gIGpvdXJuYWxOYW1lc3BhY2U6IHN0cmluZztcbn1cblxuZXhwb3J0IGNvbnN0IEdSQVBISVRJX0NPTkZJR19TQ0hFTUEgPSB7XG4gIHR5cGU6IFwib2JqZWN0XCIsXG4gIHByb3BlcnRpZXM6IHtcbiAgICBwdWJsaWNQb3J0OiB7IHR5cGU6IFwiaW50ZWdlclwiLCBtaW5pbXVtOiAxLCBtYXhpbXVtOiA2NTUzNSB9LFxuICAgIGFwcFBvcnQ6IHsgdHlwZTogXCJpbnRlZ2VyXCIsIG1pbmltdW06IDEsIG1heGltdW06IDY1NTM1IH0sXG4gICAgZ3JhcGhpdGlQb3J0OiB7IHR5cGU6IFwiaW50ZWdlclwiLCBtaW5pbXVtOiAxLCBtYXhpbXVtOiA2NTUzNSB9LFxuICAgIGxpdGVsbG1Qb3J0OiB7IHR5cGU6IFwiaW50ZWdlclwiLCBtaW5pbXVtOiAxLCBtYXhpbXVtOiA2NTUzNSB9LFxuICAgIHJvdXRlUHJlZml4OiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICBweXRob246IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgIGpvdXJuYWxOYW1lc3BhY2U6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICB9LFxuICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG59IHNhdGlzZmllcyBKU09OU2NoZW1hNztcblxuLyoqIFJlc29sdmUgcGx1Z2luIGNvbmZpZyBvdmVyIGV4YWN0IGVudmlyb25tZW50IHZhbHVlcyBhbmQgc3RhYmxlIGRlZmF1bHRzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVHcmFwaGl0aUNvbmZpZyhcbiAgY29uZmlnOiBHcmFwaGl0aVBsdWdpbkNvbmZpZyA9IHt9LFxuKTogUmVzb2x2ZWRHcmFwaGl0aVBsdWdpbkNvbmZpZyB7XG4gIGNvbnN0IHB1YmxpY1BvcnQgPSBjb3JlQ29uZmlnLnBvcnQoXG4gICAgY29uZmlnLnB1YmxpY1BvcnQsXG4gICAgXCJEQVRBQlJJQ0tTX0FQUF9QT1JUXCIsXG4gICAgODAwMCxcbiAgICBjb3JlQ29uZmlnLkVOVl9PTkxZLFxuICApO1xuICBjb25zdCBhcHBQb3J0ID0gY29yZUNvbmZpZy5wb3J0KFxuICAgIGNvbmZpZy5hcHBQb3J0LFxuICAgIFwiR1JBUEhJVElfQVBQX1BPUlRcIixcbiAgICBwdWJsaWNQb3J0ICsgMSxcbiAgICBjb3JlQ29uZmlnLkVOVl9PTkxZLFxuICApO1xuICBjb25zdCBncmFwaGl0aVBvcnQgPSBjb3JlQ29uZmlnLnBvcnQoXG4gICAgY29uZmlnLmdyYXBoaXRpUG9ydCxcbiAgICBcIkdSQVBISVRJX1BPUlRcIixcbiAgICAwLFxuICAgIGNvcmVDb25maWcuRU5WX09OTFksXG4gICk7XG4gIGNvbnN0IGxpdGVsbG1Qb3J0ID0gY29yZUNvbmZpZy5wb3J0KGNvbmZpZy5saXRlbGxtUG9ydCwgXCJMSVRFTExNX1BPUlRcIiwgMCwgY29yZUNvbmZpZy5FTlZfT05MWSk7XG4gIGNvbnN0IGNvbmZpZ3VyZWRQb3J0cyA9IFtwdWJsaWNQb3J0LCBhcHBQb3J0LCBncmFwaGl0aVBvcnQsIGxpdGVsbG1Qb3J0XS5maWx0ZXIoQm9vbGVhbik7XG4gIGlmIChuZXcgU2V0KGNvbmZpZ3VyZWRQb3J0cykuc2l6ZSAhPT0gY29uZmlndXJlZFBvcnRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBDb25maWd1cmF0aW9uRXJyb3IoXCJHcmFwaGl0aSBwdWJsaWMsIEFwcEtpdCwgYW5kIHNpZGVjYXIgcG9ydHMgbXVzdCBiZSBkaXN0aW5jdFwiKTtcbiAgfVxuICBjb25zdCByb3V0ZVByZWZpeCA9IG5vcm1hbGl6ZVJvdXRlUHJlZml4KFxuICAgIGNvbmZpZy5yb3V0ZVByZWZpeCA/P1xuICAgICAgY29yZUNvbmZpZy50ZXh0KFwiR1JBUEhJVElfUk9VVEVfUFJFRklYXCIsIGNvcmVDb25maWcuRU5WX09OTFkpID8/XG4gICAgICBcIi9ncmFwaGl0aVwiLFxuICApO1xuICBjb25zdCBweXRob24gPVxuICAgIGNvbmZpZy5weXRob24gPz8gY29yZUNvbmZpZy50ZXh0KFwiUFlUSE9OXCIsIGNvcmVDb25maWcuRU5WX09OTFkpPy50cmltKCkgPz8gXCJweXRob24zXCI7XG4gIGNvbnN0IGpvdXJuYWxOYW1lc3BhY2UgPVxuICAgIGNvbmZpZy5qb3VybmFsTmFtZXNwYWNlID8/XG4gICAgY29yZUNvbmZpZy50ZXh0KFwiSk9VUk5BTF9OQU1FU1BBQ0VcIiwgY29yZUNvbmZpZy5FTlZfT05MWSk/LnRyaW0oKSA/P1xuICAgIHByb2Nlc3MuZW52LkRBVEFCUklDS1NfQVBQX05BTUU/LnRyaW0oKSA/P1xuICAgIFwiZGVmYXVsdFwiO1xuICByZXR1cm4ge1xuICAgIHB1YmxpY1BvcnQsXG4gICAgYXBwUG9ydCxcbiAgICBncmFwaGl0aVBvcnQsXG4gICAgbGl0ZWxsbVBvcnQsXG4gICAgcm91dGVQcmVmaXgsXG4gICAgcHl0aG9uLFxuICAgIGpvdXJuYWxOYW1lc3BhY2UsXG4gIH07XG59XG5cbi8qKiBSZXR1cm4gdGhlIGludGVybmFsIHBvcnQgYW4gQXBwS2l0IGBzZXJ2ZXIoKWAgcGx1Z2luIHNob3VsZCBiaW5kLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcFBvcnQoY29uZmlnOiBHcmFwaGl0aVBsdWdpbkNvbmZpZyA9IHt9KTogbnVtYmVyIHtcbiAgcmV0dXJuIHJlc29sdmVHcmFwaGl0aUNvbmZpZyhjb25maWcpLmFwcFBvcnQ7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJvdXRlUHJlZml4KHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBub3JtYWxpemVkID0gYC8ke3ZhbHVlLnRyaW0oKS5yZXBsYWNlKC9eXFwvK3xcXC8rJC9nLCBcIlwiKX1gO1xuICBpZiAobm9ybWFsaXplZCA9PT0gXCIvXCIpIHtcbiAgICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKFwiR3JhcGhpdGkgcm91dGVQcmVmaXggbXVzdCBjb250YWluIGEgcGF0aCBzZWdtZW50XCIpO1xuICB9XG4gIHJldHVybiBub3JtYWxpemVkO1xufVxuIl19
@@ -23,6 +23,7 @@ export declare class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
23
23
  exports(): {
24
24
  appPort: number;
25
25
  graphitiPort: number;
26
+ litellmPort: number;
26
27
  mcpPath: string;
27
28
  publicPort: number;
28
29
  routePrefix: string;
package/lib/src/plugin.js CHANGED
@@ -38,9 +38,14 @@ export class GraphitiPlugin extends Plugin {
38
38
  stopping = false;
39
39
  async setup() {
40
40
  const configured = resolveGraphitiConfig(this.config);
41
+ const graphitiPort = configured.graphitiPort || (await availablePort());
42
+ let litellmPort = configured.litellmPort || (await availablePort());
43
+ while (litellmPort === graphitiPort)
44
+ litellmPort = await availablePort();
41
45
  this.resolved = {
42
46
  ...configured,
43
- graphitiPort: configured.graphitiPort || (await availablePort()),
47
+ graphitiPort,
48
+ litellmPort,
44
49
  };
45
50
  if (!process.env.LAKEBASE_ENDPOINT && !process.env.PGHOST) {
46
51
  throw new Error("Graphiti requires Lakebase; register lakebase() before graphiti() and bind its Postgres resource");
@@ -56,6 +61,9 @@ export class GraphitiPlugin extends Plugin {
56
61
  GRAPHITI_HOST: "127.0.0.1",
57
62
  GRAPHITI_PORT: String(this.resolved.graphitiPort),
58
63
  JOURNAL_NAMESPACE: this.resolved.journalNamespace,
64
+ LITELLM_HOST: "127.0.0.1",
65
+ LITELLM_PORT: String(this.resolved.litellmPort),
66
+ MANAGE_LITELLM: "true",
59
67
  },
60
68
  stdin: "ignore",
61
69
  stdout: "inherit",
@@ -98,6 +106,7 @@ export class GraphitiPlugin extends Plugin {
98
106
  this.logger.info("ready", {
99
107
  appPort: this.resolved.appPort,
100
108
  graphitiPort: this.resolved.graphitiPort,
109
+ litellmPort: this.resolved.litellmPort,
101
110
  publicPort: this.resolved.publicPort,
102
111
  mcpPath: `${this.resolved.routePrefix}/mcp/`,
103
112
  tools: Object.keys(this.mcpTools),
@@ -120,6 +129,7 @@ export class GraphitiPlugin extends Plugin {
120
129
  return {
121
130
  appPort: resolved.appPort,
122
131
  graphitiPort: resolved.graphitiPort,
132
+ litellmPort: resolved.litellmPort,
123
133
  mcpPath: `${resolved.routePrefix}/mcp/`,
124
134
  publicPort: resolved.publicPort,
125
135
  routePrefix: resolved.routePrefix,
@@ -191,4 +201,4 @@ async function availablePort() {
191
201
  });
192
202
  });
193
203
  }
194
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN4QyxPQUFPLEVBQ0wsTUFBTSxFQUNOLFFBQVEsRUFDUixRQUFRLEdBR1QsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsV0FBVyxJQUFJLGlCQUFpQixFQUFFLE1BQU0sSUFBSSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3RixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLEtBQUssSUFBSSxXQUFXLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFbkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLHFCQUFxQixHQUd0QixNQUFNLGFBQWEsQ0FBQztBQUVyQixNQUFNLGlCQUFpQixHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztBQVl0RSxNQUFNLE9BQU8sY0FBZSxTQUFRLE1BQTRCO0lBQzlELE1BQU0sQ0FBQyxRQUFRLEdBQStCO1FBQzVDLElBQUksRUFBRSxVQUFVO1FBQ2hCLFdBQVcsRUFBRSxVQUFVO1FBQ3ZCLFdBQVcsRUFDVCw0RUFBNEU7WUFDNUUsd0RBQXdEO1FBQzFELFNBQVMsRUFBRSxNQUFNO1FBQ2pCLFNBQVMsRUFBRTtZQUNULFFBQVEsRUFBRSxFQUFFO1lBQ1osUUFBUSxFQUFFLENBQUMsR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDO1NBQ3BEO1FBQ0QsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLHNCQUFzQixFQUFFO0tBQzNDLENBQUM7SUFFRixNQUFNLENB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RSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0UsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFwcEtpdCBwbHVnaW4gdGhhdCBzdXBlcnZpc2VzIEdyYXBoaXRpIGFuZCBhIENhZGR5IHNpbmdsZS1wb3J0IHByb3h5LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0IHsgY3JlYXRlU2VydmVyIH0gZnJvbSBcIm5vZGU6bmV0XCI7XG5pbXBvcnQge1xuICBQbHVnaW4sXG4gIGxha2ViYXNlLFxuICB0b1BsdWdpbixcbiAgdHlwZSBQbHVnaW5NYW5pZmVzdCxcbiAgdHlwZSBSZXNvdXJjZVJlcXVpcmVtZW50LFxufSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBpbnRlcmNlcHRvciBhcyBhcHBraXRJbnRlcmNlcHRvciwgcGx1Z2luIGFzIGFwcGtpdFBsdWdpbiB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdFwiO1xuaW1wb3J0IHsgZXhlYyB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IGFzeW5jIGFzIGFzeW5jTW9kdWxlLCBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHR5cGUgeyBUb29sIH0gZnJvbSBcIkBtYXN0cmEvY29yZS90b29sc1wiO1xuaW1wb3J0IHsgTUNQQ2xpZW50IH0gZnJvbSBcIkBtYXN0cmEvbWNwXCI7XG5pbXBvcnQge1xuICBHUkFQSElUSV9DT05GSUdfU0NIRU1BLFxuICByZXNvbHZlR3JhcGhpdGlDb25maWcsXG4gIHR5cGUgR3JhcGhpdGlQbHVnaW5Db25maWcsXG4gIHR5cGUgUmVzb2x2ZWRHcmFwaGl0aVBsdWdpbkNvbmZpZyxcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5cbmNvbnN0IExBS0VCQVNFX01BTklGRVNUID0gYXBwa2l0UGx1Z2luLmRhdGEobGFrZWJhc2UpLnBsdWdpbi5tYW5pZmVzdDtcblxuaW50ZXJmYWNlIFRvb2xraXRFbnRyeSB7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgbG9jYWxOYW1lOiBzdHJpbmc7XG4gIGRlZjoge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICAgIHBhcmFtZXRlcnM6IHVua25vd247XG4gIH07XG59XG5cbmV4cG9ydCBjbGFzcyBHcmFwaGl0aVBsdWdpbiBleHRlbmRzIFBsdWdpbjxHcmFwaGl0aVBsdWdpbkNvbmZpZz4ge1xuICBzdGF0aWMgbWFuaWZlc3Q6IFBsdWdpbk1hbmlmZXN0PFwiZ3JhcGhpdGlcIj4gPSB7XG4gICAgbmFtZTogXCJncmFwaGl0aVwiLFxuICAgIGRpc3BsYXlOYW1lOiBcIkdyYXBoaXRpXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1bnMgdGhlIGRieC10b29scyBHcmFwaGl0aSBNQ1Agc2lkZWNhciB3aXRoIExha2ViYXNlLWJhY2tlZCByZWNvdmVyeSBhbmQgXCIgK1xuICAgICAgXCJwdWJsaXNoZXMgaXQgdGhyb3VnaCB0aGUgQXBwJ3Mgc2luZ2xlIHBvcnQgd2l0aCBDYWRkeS5cIixcbiAgICBzdGFiaWxpdHk6IFwiYmV0YVwiLFxuICAgIHJlc291cmNlczoge1xuICAgICAgcmVxdWlyZWQ6IFtdLFxuICAgICAgb3B0aW9uYWw6IFsuLi5MQUtFQkFTRV9NQU5JRkVTVC5yZXNvdXJjZXMucmVxdWlyZWRdLFxuICAgIH0sXG4gICAgY29uZmlnOiB7IHNjaGVtYTogR1JBUEhJVElfQ09ORklHX1NDSEVNQSB9LFxuICB9O1xuXG4gIHN0YXRpYyBnZXRSZXNvdXJjZVJlcXVpcmVtZW50cygpOiBSZXNvdXJjZVJlcXVpcmVtZW50W10ge1xuICAgIHJldHVybiBMQUtFQkFTRV9NQU5JRkVTVC5yZXNvdXJjZXMucmVxdWlyZWQubWFwKChyZXNvdXJjZSkgPT4gKHtcbiAgICAgIC4uLnJlc291cmNlLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgfSkpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXIgPSBsb2cubG9nZ2VyKHRoaXMpO1xuICBwcml2YXRlIGNoaWxkcmVuOiBSZXR1cm5UeXBlPHR5cGVvZiBleGVjLnNwYXduPltdID0gW107XG4gIHByaXZhdGUgbWNwPzogTUNQQ2xpZW50O1xuICBwcml2YXRlIG1jcFRvb2xzOiBSZWNvcmQ8c3RyaW5nLCBUb29sPiA9IHt9O1xuICBwcml2YXRlIHJlc29sdmVkPzogUmVzb2x2ZWRHcmFwaGl0aVBsdWdpbkNvbmZpZztcbiAgcHJpdmF0ZSBzdG9wcGluZyA9IGZhbHNlO1xuXG4gIG92ZXJyaWRlIGFzeW5jIHNldHVwKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbmZpZ3VyZWQgPSByZXNvbHZlR3JhcGhpdGlDb25maWcodGhpcy5jb25maWcpO1xuICAgIHRoaXMucmVzb2x2ZWQgPSB7XG4gICAgICAuLi5jb25maWd1cmVkLFxuICAgICAgZ3JhcGhpdGlQb3J0OiBjb25maWd1cmVkLmdyYXBoaXRpUG9ydCB8fCAoYXdhaXQgYXZhaWxhYmxlUG9ydCgpKSxcbiAgICB9O1xuICAgIGlmICghcHJvY2Vzcy5lbnYuTEFLRUJBU0VfRU5EUE9JTlQgJiYgIXByb2Nlc3MuZW52LlBHSE9TVCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIkdyYXBoaXRpIHJlcXVpcmVzIExha2ViYXNlOyByZWdpc3RlciBsYWtlYmFzZSgpIGJlZm9yZSBncmFwaGl0aSgpIGFuZCBiaW5kIGl0cyBQb3N0Z3JlcyByZXNvdXJjZVwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzaWduYWwgb2YgW1wiU0lHSU5UXCIsIFwiU0lHVEVSTVwiLCBcIlNJR0hVUFwiXSBhcyBjb25zdCkge1xuICAgICAgcHJvY2Vzcy5vbmNlKHNpZ25hbCwgKCkgPT4gdGhpcy5zdG9wR3JhcGhpdGkoKSk7XG4gICAgfVxuICAgIGNvbnN0IHN1cGVydmlzb3IgPSBhcHBraXRJbnRlcmNlcHRvci5jcmVhdGVJbnRlcmNlcHRvckNvbnRleHQoe30pO1xuICAgIHN1cGVydmlzb3IuY29udGV4dC5vblRlYXJkb3duKCgpID0+IHRoaXMuc3RvcEdyYXBoaXRpKCkpO1xuICAgIGNvbnN0IGdyYXBoaXRpID0gZXhlYy5zcGF3bih0aGlzLnJlc29sdmVkLnB5dGhvbiwgW1wiLW1cIiwgXCJkYnhfdG9vbHMuZ3JhcGhpdGlcIiwgXCJzdGFydFwiXSwge1xuICAgICAgZW52OiB7XG4gICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICBHUkFQSElUSV9IT1NUOiBcIjEyNy4wLjAuMVwiLFxuICAgICAgICBHUkFQSElUSV9QT1JUOiBTdHJpbmcodGhpcy5yZXNvbHZlZC5ncmFwaGl0aVBvcnQpLFxuICAgICAgICBKT1VSTkFMX05BTUVTUEFDRTogdGhpcy5yZXNvbHZlZC5qb3VybmFsTmFtZXNwYWNlLFxuICAgICAgfSxcbiAgICAgIHN0ZGluOiBcImlnbm9yZVwiLFxuICAgICAgc3Rkb3V0OiBcImluaGVyaXRcIixcbiAgICAgIHN0ZGVycjogXCJpbmhlcml0XCIsXG4gICAgfSk7XG4gICAgY29uc3QgY2FkZHkgPSBleGVjLnNwYXduKFxuICAgICAgdGhpcy5yZXNvbHZlZC5weXRob24sXG4gICAgICBbXG4gICAgICAgIFwiLW1cIixcbiAgICAgICAgXCJkYnhfdG9vbHMuZ3JhcGhpdGkucHJveHlcIixcbiAgICAgICAgXCItLXB1YmxpYy1wb3J0XCIsXG4gICAgICAgIFN0cmluZyh0aGlzLnJlc29sdmVkLnB1YmxpY1BvcnQpLFxuICAgICAgICBcIi0tYXBwLXBvcnRcIixcbiAgICAgICAgU3RyaW5nKHRoaXMucmVzb2x2ZWQuYXBwUG9ydCksXG4gICAgICAgIFwiLS1ncmFwaGl0aS1wb3J0XCIsXG4gICAgICAgIFN0cmluZyh0aGlzLnJlc29sdmVkLmdyYXBoaXRpUG9ydCksXG4gICAgICAgIFwiLS1yb3V0ZS1wcmVmaXhcIixcbiAgICAgICAgdGhpcy5yZXNvbHZlZC5yb3V0ZVByZWZpeCxcbiAgICAgIF0sXG4gICAgICB7XG4gICAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICAgIHN0ZGluOiBcImlnbm9yZVwiLFxuICAgICAgICBzdGRvdXQ6IFwiaW5oZXJpdFwiLFxuICAgICAgICBzdGRlcnI6IFwiaW5oZXJpdFwiLFxuICAgICAgfSxcbiAgICApO1xuICAgIHRoaXMuY2hpbGRyZW4gPSBbZ3JhcGhpdGksIGNhZGR5XTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHRoaXMuY2hpbGRyZW4pIHN1cGVydmlzb3IuY29udGV4dC5iaW5kUHJvY2VzcyhjaGlsZCk7XG4gICAgYXdhaXQgd2FpdEZvckdyYXBoaXRpKHRoaXMucmVzb2x2ZWQuZ3JhcGhpdGlQb3J0KTtcbiAgICB0aGlzLm1jcCA9IG5ldyBNQ1BDbGllbnQoe1xuICAgICAgaWQ6IGBhcHBraXQtZ3JhcGhpdGktJHt0aGlzLnJlc29sdmVkLmdyYXBoaXRpUG9ydH1gLFxuICAgICAgc2VydmVyczoge1xuICAgICAgICBncmFwaGl0aToge1xuICAgICAgICAgIHVybDogbmV3IFVSTChgaHR0cDovLzEyNy4wLjAuMToke3RoaXMucmVzb2x2ZWQuZ3JhcGhpdGlQb3J0fS9tY3BgKSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgY29uc3QgZGlzY292ZXJlZCA9IGF3YWl0IHRoaXMubWNwLmxpc3RUb29scygpO1xuICAgIHRoaXMubWNwVG9vbHMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyhkaXNjb3ZlcmVkKS5tYXAoKFtuYW1lLCB0b29sXSkgPT4gW1xuICAgICAgICBuYW1lLnJlcGxhY2UoL15ncmFwaGl0aV8vLCBcIlwiKSxcbiAgICAgICAgdG9vbCBhcyBUb29sLFxuICAgICAgXSksXG4gICAgKTtcbiAgICB0aGlzLmxvZ2dlci5pbmZvKFwicmVhZHlcIiwge1xuICAgICAgYXBwUG9ydDogdGhpcy5yZXNvbHZlZC5hcHBQb3J0LFxuICAgICAgZ3JhcGhpdGlQb3J0OiB0aGlzLnJlc29sdmVkLmdyYXBoaXRpUG9ydCxcbiAgICAgIHB1YmxpY1BvcnQ6IHRoaXMucmVzb2x2ZWQucHVibGljUG9ydCxcbiAgICAgIG1jcFBhdGg6IGAke3RoaXMucmVzb2x2ZWQucm91dGVQcmVmaXh9L21jcC9gLFxuICAgICAgdG9vbHM6IE9iamVjdC5rZXlzKHRoaXMubWNwVG9vbHMpLFxuICAgIH0pO1xuICB9XG5cbiAgb3ZlcnJpZGUgYWJvcnRBY3RpdmVPcGVyYXRpb25zKCk6IHZvaWQge1xuICAgIHN1cGVyLmFib3J0QWN0aXZlT3BlcmF0aW9ucygpO1xuICAgIHRoaXMuc3RvcEdyYXBoaXRpKCk7XG4gICAgdm9pZCB0aGlzLm1jcD8uZGlzY29ubmVjdCgpO1xuICAgIHRoaXMubWNwID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWNwVG9vbHMgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHRoaXMuY2hpbGRyZW4pIHtcbiAgICAgIGlmICghY2hpbGQua2lsbGVkKSBjaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICB9XG4gICAgdGhpcy5jaGlsZHJlbiA9IFtdO1xuICB9XG5cbiAgb3ZlcnJpZGUgZXhwb3J0cygpIHtcbiAgICBjb25zdCByZXNvbHZlZCA9IHRoaXMucmVzb2x2ZWQgPz8gcmVzb2x2ZUdyYXBoaXRpQ29uZmlnKHRoaXMuY29uZmlnKTtcbiAgICByZXR1cm4ge1xuICAgICAgYXBwUG9ydDogcmVzb2x2ZWQuYXBwUG9ydCxcbiAgICAgIGdyYXBoaXRpUG9ydDogcmVzb2x2ZWQuZ3JhcGhpdGlQb3J0LFxuICAgICAgbWNwUGF0aDogYCR7cmVzb2x2ZWQucm91dGVQcmVmaXh9L21jcC9gLFxuICAgICAgcHVibGljUG9ydDogcmVzb2x2ZWQucHVibGljUG9ydCxcbiAgICAgIHJvdXRlUHJlZml4OiByZXNvbHZlZC5yb3V0ZVByZWZpeCxcbiAgICB9O1xuICB9XG5cbiAgdG9vbGtpdCgpOiBSZWNvcmQ8c3RyaW5nLCBUb29sa2l0RW50cnk+IHtcbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXModGhpcy5tY3BUb29scykubWFwKChbbmFtZSwgdG9vbF0pID0+IFtcbiAgICAgICAgbmFtZSxcbiAgICAgICAge1xuICAgICAgICAgIHBsdWdpbk5hbWU6IFwiZ3JhcGhpdGlcIixcbiAgICAgICAgICBsb2NhbE5hbWU6IG5hbWUsXG4gICAgICAgICAgZGVmOiB7XG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHRvb2wuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBwYXJhbWV0ZXJzOiB0b29sLmlucHV0U2NoZW1hID8/IHsgdHlwZTogXCJvYmplY3RcIiwgcHJvcGVydGllczoge30gfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSksXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGV4ZWN1dGVBZ2VudFRvb2wobmFtZTogc3RyaW5nLCBhcmdzOiB1bmtub3duLCBzaWduYWw/OiBBYm9ydFNpZ25hbCk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGNvbnN0IHRvb2wgPSB0aGlzLm1jcFRvb2xzW25hbWVdO1xuICAgIGlmICghdG9vbD8uZXhlY3V0ZSkgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIEdyYXBoaXRpIHRvb2w6ICR7bmFtZX1gKTtcbiAgICByZXR1cm4gdG9vbC5leGVjdXRlKGFyZ3MsIHsgYWJvcnRTaWduYWw6IHNpZ25hbCB9IGFzIG5ldmVyKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcEdyYXBoaXRpKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN0b3BwaW5nIHx8ICF0aGlzLnJlc29sdmVkKSByZXR1cm47XG4gICAgdGhpcy5zdG9wcGluZyA9IHRydWU7XG4gICAgdm9pZCBleGVjLnNwYXduKHRoaXMucmVzb2x2ZWQucHl0aG9uLCBbXCItbVwiLCBcImRieF90b29scy5ncmFwaGl0aVwiLCBcImRvd25cIl0sIHtcbiAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICBzdGRpbjogXCJpZ25vcmVcIixcbiAgICAgIHN0ZG91dDogXCJpbmhlcml0XCIsXG4gICAgICBzdGRlcnI6IFwiaW5oZXJpdFwiLFxuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBncmFwaGl0aSA9IHRvUGx1Z2luKEdyYXBoaXRpUGx1Z2luKTtcblxuYXN5bmMgZnVuY3Rpb24gd2FpdEZvckdyYXBoaXRpKHBvcnQ6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICBmb3IgYXdhaXQgKGNvbnN0IHJlYWR5IG9mIGFzeW5jTW9kdWxlLnBvbGwoXG4gICAgYXN5bmMgKHsgc2lnbmFsIH0pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYGh0dHA6Ly8xMjcuMC4wLjE6JHtwb3J0fS9oZWFsdGhgLCB7IHNpZ25hbCB9KTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLm9rO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9LFxuICAgIHtcbiAgICAgIGludGVydmFsTXM6IDI1MCxcbiAgICAgIHRpbWVvdXRNczogNjBfMDAwLFxuICAgICAgcHJlZGljYXRlOiAocmVhZHkpID0+ICFyZWFkeSxcbiAgICB9LFxuICApKSB7XG4gICAgaWYgKHJlYWR5KSByZXR1cm47XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gYXZhaWxhYmxlUG9ydCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHNlcnZlciA9IGNyZWF0ZVNlcnZlcigpO1xuICAgIHNlcnZlci5vbmNlKFwiZXJyb3JcIiwgcmVqZWN0KTtcbiAgICBzZXJ2ZXIubGlzdGVuKDAsIFwiMTI3LjAuMC4xXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBzZXJ2ZXIuYWRkcmVzcygpO1xuICAgICAgaWYgKCFhZGRyZXNzIHx8IHR5cGVvZiBhZGRyZXNzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKFwiQ291bGQgbm90IGFsbG9jYXRlIGEgR3JhcGhpdGkgbG9vcGJhY2sgcG9ydFwiKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNlcnZlci5jbG9zZSgoZXJyb3IpID0+IChlcnJvciA/IHJlamVjdChlcnJvcikgOiByZXNvbHZlKGFkZHJlc3MucG9ydCkpKTtcbiAgICB9KTtcbiAgfSk7XG59XG4iXX0=
204
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN4QyxPQUFPLEVBQ0wsTUFBTSxFQUNOLFFBQVEsRUFDUixRQUFRLEdBR1QsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsV0FBVyxJQUFJLGlCQUFpQixFQUFFLE1BQU0sSUFBSSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3RixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLEtBQUssSUFBSSxXQUFXLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFbkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLHFCQUFxQixHQUd0QixNQUFNLGFBQWEsQ0FBQztBQUVyQixNQUFNLGlCQUFpQixHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztBQVl0RSxNQUFNLE9BQU8sY0FBZSxTQUFRLE1BQTRCO0lBQzlELE1BQU0sQ0FBQyxRQUFRLEdBQStCO1FBQzVDLElBQUksRUFBRSxVQUFVO1FBQ2hCLFdBQVcsRUFBRSxVQUFVO1FBQ3ZCLFdBQVcsRUFDVCw0RUFBNEU7WUFDNUUsd0RBQXdEO1FBQzFELFNBQVMsRUFBRSxNQUFNO1FBQ2pCLFNBQVMsRUFBRTtZQUNULFFBQVEsRUFBRSxFQUFFO1lBQ1osUUFBUSxFQUFFLENBQUMsR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDO1NBQ3BEO1FBQ0QsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLHNCQUFzQixFQUFFO0tBQzNDLENBQUM7SUFFRixNQUFNLENB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SSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUM3QixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsR0FBRyxFQUFFO1lBQ2pDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUM1QyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLDZDQUE2QyxDQUFDLENBQUMsQ0FBQztnQkFDakUsT0FBTztZQUNULENBQUM7WUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXBwS2l0IHBsdWdpbiB0aGF0IHN1cGVydmlzZXMgR3JhcGhpdGkgYW5kIGEgQ2FkZHkgc2luZ2xlLXBvcnQgcHJveHkuXG4gKlxuICogQG1vZHVsZVxuICovXG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXIgfSBmcm9tIFwibm9kZTpuZXRcIjtcbmltcG9ydCB7XG4gIFBsdWdpbixcbiAgbGFrZWJhc2UsXG4gIHRvUGx1Z2luLFxuICB0eXBlIFBsdWdpbk1hbmlmZXN0LFxuICB0eXBlIFJlc291cmNlUmVxdWlyZW1lbnQsXG59IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGludGVyY2VwdG9yIGFzIGFwcGtpdEludGVyY2VwdG9yLCBwbHVnaW4gYXMgYXBwa2l0UGx1Z2luIH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSBcIkBkYngtdG9vbHMvY29yZVwiO1xuaW1wb3J0IHsgYXN5bmMgYXMgYXN5bmNNb2R1bGUsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IFRvb2wgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL3Rvb2xzXCI7XG5pbXBvcnQgeyBNQ1BDbGllbnQgfSBmcm9tIFwiQG1hc3RyYS9tY3BcIjtcbmltcG9ydCB7XG4gIEdSQVBISVRJX0NPTkZJR19TQ0hFTUEsXG4gIHJlc29sdmVHcmFwaGl0aUNvbmZpZyxcbiAgdHlwZSBHcmFwaGl0aVBsdWdpbkNvbmZpZyxcbiAgdHlwZSBSZXNvbHZlZEdyYXBoaXRpUGx1Z2luQ29uZmlnLFxufSBmcm9tIFwiLi9jb25maWcudHNcIjtcblxuY29uc3QgTEFLRUJBU0VfTUFOSUZFU1QgPSBhcHBraXRQbHVnaW4uZGF0YShsYWtlYmFzZSkucGx1Z2luLm1hbmlmZXN0O1xuXG5pbnRlcmZhY2UgVG9vbGtpdEVudHJ5IHtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBsb2NhbE5hbWU6IHN0cmluZztcbiAgZGVmOiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgcGFyYW1ldGVyczogdW5rbm93bjtcbiAgfTtcbn1cblxuZXhwb3J0IGNsYXNzIEdyYXBoaXRpUGx1Z2luIGV4dGVuZHMgUGx1Z2luPEdyYXBoaXRpUGx1Z2luQ29uZmlnPiB7XG4gIHN0YXRpYyBtYW5pZmVzdDogUGx1Z2luTWFuaWZlc3Q8XCJncmFwaGl0aVwiPiA9IHtcbiAgICBuYW1lOiBcImdyYXBoaXRpXCIsXG4gICAgZGlzcGxheU5hbWU6IFwiR3JhcGhpdGlcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUnVucyB0aGUgZGJ4LXRvb2xzIEdyYXBoaXRpIE1DUCBzaWRlY2FyIHdpdGggTGFrZWJhc2UtYmFja2VkIHJlY292ZXJ5IGFuZCBcIiArXG4gICAgICBcInB1Ymxpc2hlcyBpdCB0aHJvdWdoIHRoZSBBcHAncyBzaW5nbGUgcG9ydCB3aXRoIENhZGR5LlwiLFxuICAgIHN0YWJpbGl0eTogXCJiZXRhXCIsXG4gICAgcmVzb3VyY2VzOiB7XG4gICAgICByZXF1aXJlZDogW10sXG4gICAgICBvcHRpb25hbDogWy4uLkxBS0VCQVNFX01BTklGRVNULnJlc291cmNlcy5yZXF1aXJlZF0sXG4gICAgfSxcbiAgICBjb25maWc6IHsgc2NoZW1hOiBHUkFQSElUSV9DT05GSUdfU0NIRU1BIH0sXG4gIH07XG5cbiAgc3RhdGljIGdldFJlc291cmNlUmVxdWlyZW1lbnRzKCk6IFJlc291cmNlUmVxdWlyZW1lbnRbXSB7XG4gICAgcmV0dXJuIExBS0VCQVNFX01BTklGRVNULnJlc291cmNlcy5yZXF1aXJlZC5tYXAoKHJlc291cmNlKSA9PiAoe1xuICAgICAgLi4ucmVzb3VyY2UsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICB9KSk7XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlciA9IGxvZy5sb2dnZXIodGhpcyk7XG4gIHByaXZhdGUgY2hpbGRyZW46IFJldHVyblR5cGU8dHlwZW9mIGV4ZWMuc3Bhd24+W10gPSBbXTtcbiAgcHJpdmF0ZSBtY3A/OiBNQ1BDbGllbnQ7XG4gIHByaXZhdGUgbWNwVG9vbHM6IFJlY29yZDxzdHJpbmcsIFRvb2w+ID0ge307XG4gIHByaXZhdGUgcmVzb2x2ZWQ/OiBSZXNvbHZlZEdyYXBoaXRpUGx1Z2luQ29uZmlnO1xuICBwcml2YXRlIHN0b3BwaW5nID0gZmFsc2U7XG5cbiAgb3ZlcnJpZGUgYXN5bmMgc2V0dXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29uZmlndXJlZCA9IHJlc29sdmVHcmFwaGl0aUNvbmZpZyh0aGlzLmNvbmZpZyk7XG4gICAgY29uc3QgZ3JhcGhpdGlQb3J0ID0gY29uZmlndXJlZC5ncmFwaGl0aVBvcnQgfHwgKGF3YWl0IGF2YWlsYWJsZVBvcnQoKSk7XG4gICAgbGV0IGxpdGVsbG1Qb3J0ID0gY29uZmlndXJlZC5saXRlbGxtUG9ydCB8fCAoYXdhaXQgYXZhaWxhYmxlUG9ydCgpKTtcbiAgICB3aGlsZSAobGl0ZWxsbVBvcnQgPT09IGdyYXBoaXRpUG9ydCkgbGl0ZWxsbVBvcnQgPSBhd2FpdCBhdmFpbGFibGVQb3J0KCk7XG4gICAgdGhpcy5yZXNvbHZlZCA9IHtcbiAgICAgIC4uLmNvbmZpZ3VyZWQsXG4gICAgICBncmFwaGl0aVBvcnQsXG4gICAgICBsaXRlbGxtUG9ydCxcbiAgICB9O1xuICAgIGlmICghcHJvY2Vzcy5lbnYuTEFLRUJBU0VfRU5EUE9JTlQgJiYgIXByb2Nlc3MuZW52LlBHSE9TVCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIkdyYXBoaXRpIHJlcXVpcmVzIExha2ViYXNlOyByZWdpc3RlciBsYWtlYmFzZSgpIGJlZm9yZSBncmFwaGl0aSgpIGFuZCBiaW5kIGl0cyBQb3N0Z3JlcyByZXNvdXJjZVwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzaWduYWwgb2YgW1wiU0lHSU5UXCIsIFwiU0lHVEVSTVwiLCBcIlNJR0hVUFwiXSBhcyBjb25zdCkge1xuICAgICAgcHJvY2Vzcy5vbmNlKHNpZ25hbCwgKCkgPT4gdGhpcy5zdG9wR3JhcGhpdGkoKSk7XG4gICAgfVxuICAgIGNvbnN0IHN1cGVydmlzb3IgPSBhcHBraXRJbnRlcmNlcHRvci5jcmVhdGVJbnRlcmNlcHRvckNvbnRleHQoe30pO1xuICAgIHN1cGVydmlzb3IuY29udGV4dC5vblRlYXJkb3duKCgpID0+IHRoaXMuc3RvcEdyYXBoaXRpKCkpO1xuICAgIGNvbnN0IGdyYXBoaXRpID0gZXhlYy5zcGF3bih0aGlzLnJlc29sdmVkLnB5dGhvbiwgW1wiLW1cIiwgXCJkYnhfdG9vbHMuZ3JhcGhpdGlcIiwgXCJzdGFydFwiXSwge1xuICAgICAgZW52OiB7XG4gICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICBHUkFQSElUSV9IT1NUOiBcIjEyNy4wLjAuMVwiLFxuICAgICAgICBHUkFQSElUSV9QT1JUOiBTdHJpbmcodGhpcy5yZXNvbHZlZC5ncmFwaGl0aVBvcnQpLFxuICAgICAgICBKT1VSTkFMX05BTUVTUEFDRTogdGhpcy5yZXNvbHZlZC5qb3VybmFsTmFtZXNwYWNlLFxuICAgICAgICBMSVRFTExNX0hPU1Q6IFwiMTI3LjAuMC4xXCIsXG4gICAgICAgIExJVEVMTE1fUE9SVDogU3RyaW5nKHRoaXMucmVzb2x2ZWQubGl0ZWxsbVBvcnQpLFxuICAgICAgICBNQU5BR0VfTElURUxMTTogXCJ0cnVlXCIsXG4gICAgICB9LFxuICAgICAgc3RkaW46IFwiaWdub3JlXCIsXG4gICAgICBzdGRvdXQ6IFwiaW5oZXJpdFwiLFxuICAgICAgc3RkZXJyOiBcImluaGVyaXRcIixcbiAgICB9KTtcbiAgICBjb25zdCBjYWRkeSA9IGV4ZWMuc3Bhd24oXG4gICAgICB0aGlzLnJlc29sdmVkLnB5dGhvbixcbiAgICAgIFtcbiAgICAgICAgXCItbVwiLFxuICAgICAgICBcImRieF90b29scy5ncmFwaGl0aS5wcm94eVwiLFxuICAgICAgICBcIi0tcHVibGljLXBvcnRcIixcbiAgICAgICAgU3RyaW5nKHRoaXMucmVzb2x2ZWQucHVibGljUG9ydCksXG4gICAgICAgIFwiLS1hcHAtcG9ydFwiLFxuICAgICAgICBTdHJpbmcodGhpcy5yZXNvbHZlZC5hcHBQb3J0KSxcbiAgICAgICAgXCItLWdyYXBoaXRpLXBvcnRcIixcbiAgICAgICAgU3RyaW5nKHRoaXMucmVzb2x2ZWQuZ3JhcGhpdGlQb3J0KSxcbiAgICAgICAgXCItLXJvdXRlLXByZWZpeFwiLFxuICAgICAgICB0aGlzLnJlc29sdmVkLnJvdXRlUHJlZml4LFxuICAgICAgXSxcbiAgICAgIHtcbiAgICAgICAgZW52OiBwcm9jZXNzLmVudixcbiAgICAgICAgc3RkaW46IFwiaWdub3JlXCIsXG4gICAgICAgIHN0ZG91dDogXCJpbmhlcml0XCIsXG4gICAgICAgIHN0ZGVycjogXCJpbmhlcml0XCIsXG4gICAgICB9LFxuICAgICk7XG4gICAgdGhpcy5jaGlsZHJlbiA9IFtncmFwaGl0aSwgY2FkZHldO1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgdGhpcy5jaGlsZHJlbikgc3VwZXJ2aXNvci5jb250ZXh0LmJpbmRQcm9jZXNzKGNoaWxkKTtcbiAgICBhd2FpdCB3YWl0Rm9yR3JhcGhpdGkodGhpcy5yZXNvbHZlZC5ncmFwaGl0aVBvcnQpO1xuICAgIHRoaXMubWNwID0gbmV3IE1DUENsaWVudCh7XG4gICAgICBpZDogYGFwcGtpdC1ncmFwaGl0aS0ke3RoaXMucmVzb2x2ZWQuZ3JhcGhpdGlQb3J0fWAsXG4gICAgICBzZXJ2ZXJzOiB7XG4gICAgICAgIGdyYXBoaXRpOiB7XG4gICAgICAgICAgdXJsOiBuZXcgVVJMKGBodHRwOi8vMTI3LjAuMC4xOiR7dGhpcy5yZXNvbHZlZC5ncmFwaGl0aVBvcnR9L21jcGApLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBjb25zdCBkaXNjb3ZlcmVkID0gYXdhaXQgdGhpcy5tY3AubGlzdFRvb2xzKCk7XG4gICAgdGhpcy5tY3BUb29scyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKGRpc2NvdmVyZWQpLm1hcCgoW25hbWUsIHRvb2xdKSA9PiBbXG4gICAgICAgIG5hbWUucmVwbGFjZSgvXmdyYXBoaXRpXy8sIFwiXCIpLFxuICAgICAgICB0b29sIGFzIFRvb2wsXG4gICAgICBdKSxcbiAgICApO1xuICAgIHRoaXMubG9nZ2VyLmluZm8oXCJyZWFkeVwiLCB7XG4gICAgICBhcHBQb3J0OiB0aGlzLnJlc29sdmVkLmFwcFBvcnQsXG4gICAgICBncmFwaGl0aVBvcnQ6IHRoaXMucmVzb2x2ZWQuZ3JhcGhpdGlQb3J0LFxuICAgICAgbGl0ZWxsbVBvcnQ6IHRoaXMucmVzb2x2ZWQubGl0ZWxsbVBvcnQsXG4gICAgICBwdWJsaWNQb3J0OiB0aGlzLnJlc29sdmVkLnB1YmxpY1BvcnQsXG4gICAgICBtY3BQYXRoOiBgJHt0aGlzLnJlc29sdmVkLnJvdXRlUHJlZml4fS9tY3AvYCxcbiAgICAgIHRvb2xzOiBPYmplY3Qua2V5cyh0aGlzLm1jcFRvb2xzKSxcbiAgICB9KTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFib3J0QWN0aXZlT3BlcmF0aW9ucygpOiB2b2lkIHtcbiAgICBzdXBlci5hYm9ydEFjdGl2ZU9wZXJhdGlvbnMoKTtcbiAgICB0aGlzLnN0b3BHcmFwaGl0aSgpO1xuICAgIHZvaWQgdGhpcy5tY3A/LmRpc2Nvbm5lY3QoKTtcbiAgICB0aGlzLm1jcCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1jcFRvb2xzID0ge307XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiB0aGlzLmNoaWxkcmVuKSB7XG4gICAgICBpZiAoIWNoaWxkLmtpbGxlZCkgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG4gICAgfVxuICAgIHRoaXMuY2hpbGRyZW4gPSBbXTtcbiAgfVxuXG4gIG92ZXJyaWRlIGV4cG9ydHMoKSB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSB0aGlzLnJlc29sdmVkID8/IHJlc29sdmVHcmFwaGl0aUNvbmZpZyh0aGlzLmNvbmZpZyk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGFwcFBvcnQ6IHJlc29sdmVkLmFwcFBvcnQsXG4gICAgICBncmFwaGl0aVBvcnQ6IHJlc29sdmVkLmdyYXBoaXRpUG9ydCxcbiAgICAgIGxpdGVsbG1Qb3J0OiByZXNvbHZlZC5saXRlbGxtUG9ydCxcbiAgICAgIG1jcFBhdGg6IGAke3Jlc29sdmVkLnJvdXRlUHJlZml4fS9tY3AvYCxcbiAgICAgIHB1YmxpY1BvcnQ6IHJlc29sdmVkLnB1YmxpY1BvcnQsXG4gICAgICByb3V0ZVByZWZpeDogcmVzb2x2ZWQucm91dGVQcmVmaXgsXG4gICAgfTtcbiAgfVxuXG4gIHRvb2xraXQoKTogUmVjb3JkPHN0cmluZywgVG9vbGtpdEVudHJ5PiB7XG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKHRoaXMubWNwVG9vbHMpLm1hcCgoW25hbWUsIHRvb2xdKSA9PiBbXG4gICAgICAgIG5hbWUsXG4gICAgICAgIHtcbiAgICAgICAgICBwbHVnaW5OYW1lOiBcImdyYXBoaXRpXCIsXG4gICAgICAgICAgbG9jYWxOYW1lOiBuYW1lLFxuICAgICAgICAgIGRlZjoge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiB0b29sLmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgcGFyYW1ldGVyczogdG9vbC5pbnB1dFNjaGVtYSA/PyB7IHR5cGU6IFwib2JqZWN0XCIsIHByb3BlcnRpZXM6IHt9IH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0pLFxuICAgICk7XG4gIH1cblxuICBhc3luYyBleGVjdXRlQWdlbnRUb29sKG5hbWU6IHN0cmluZywgYXJnczogdW5rbm93biwgc2lnbmFsPzogQWJvcnRTaWduYWwpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICBjb25zdCB0b29sID0gdGhpcy5tY3BUb29sc1tuYW1lXTtcbiAgICBpZiAoIXRvb2w/LmV4ZWN1dGUpIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBHcmFwaGl0aSB0b29sOiAke25hbWV9YCk7XG4gICAgcmV0dXJuIHRvb2wuZXhlY3V0ZShhcmdzLCB7IGFib3J0U2lnbmFsOiBzaWduYWwgfSBhcyBuZXZlcik7XG4gIH1cblxuICBwcml2YXRlIHN0b3BHcmFwaGl0aSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdG9wcGluZyB8fCAhdGhpcy5yZXNvbHZlZCkgcmV0dXJuO1xuICAgIHRoaXMuc3RvcHBpbmcgPSB0cnVlO1xuICAgIHZvaWQgZXhlYy5zcGF3bih0aGlzLnJlc29sdmVkLnB5dGhvbiwgW1wiLW1cIiwgXCJkYnhfdG9vbHMuZ3JhcGhpdGlcIiwgXCJkb3duXCJdLCB7XG4gICAgICBlbnY6IHByb2Nlc3MuZW52LFxuICAgICAgc3RkaW46IFwiaWdub3JlXCIsXG4gICAgICBzdGRvdXQ6IFwiaW5oZXJpdFwiLFxuICAgICAgc3RkZXJyOiBcImluaGVyaXRcIixcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZ3JhcGhpdGkgPSB0b1BsdWdpbihHcmFwaGl0aVBsdWdpbik7XG5cbmFzeW5jIGZ1bmN0aW9uIHdhaXRGb3JHcmFwaGl0aShwb3J0OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgZm9yIGF3YWl0IChjb25zdCByZWFkeSBvZiBhc3luY01vZHVsZS5wb2xsKFxuICAgIGFzeW5jICh7IHNpZ25hbCB9KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGBodHRwOi8vMTI3LjAuMC4xOiR7cG9ydH0vaGVhbHRoYCwgeyBzaWduYWwgfSk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5vaztcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSxcbiAgICB7XG4gICAgICBpbnRlcnZhbE1zOiAyNTAsXG4gICAgICB0aW1lb3V0TXM6IDYwXzAwMCxcbiAgICAgIHByZWRpY2F0ZTogKHJlYWR5KSA9PiAhcmVhZHksXG4gICAgfSxcbiAgKSkge1xuICAgIGlmIChyZWFkeSkgcmV0dXJuO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGF2YWlsYWJsZVBvcnQoKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzZXJ2ZXIgPSBjcmVhdGVTZXJ2ZXIoKTtcbiAgICBzZXJ2ZXIub25jZShcImVycm9yXCIsIHJlamVjdCk7XG4gICAgc2VydmVyLmxpc3RlbigwLCBcIjEyNy4wLjAuMVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gc2VydmVyLmFkZHJlc3MoKTtcbiAgICAgIGlmICghYWRkcmVzcyB8fCB0eXBlb2YgYWRkcmVzcyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICBzZXJ2ZXIuY2xvc2UoKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIkNvdWxkIG5vdCBhbGxvY2F0ZSBhIEdyYXBoaXRpIGxvb3BiYWNrIHBvcnRcIikpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZXJ2ZXIuY2xvc2UoKGVycm9yKSA9PiAoZXJyb3IgPyByZWplY3QoZXJyb3IpIDogcmVzb2x2ZShhZGRyZXNzLnBvcnQpKSk7XG4gICAgfSk7XG4gIH0pO1xufVxuIl19
package/package.json CHANGED
@@ -25,9 +25,9 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@databricks/appkit": "^0.60.0",
28
- "@dbx-tools/appkit": "0.6.113",
29
- "@dbx-tools/core": "0.6.113",
30
- "@dbx-tools/shared-core": "0.6.113",
28
+ "@dbx-tools/appkit": "0.6.114",
29
+ "@dbx-tools/core": "0.6.114",
30
+ "@dbx-tools/shared-core": "0.6.114",
31
31
  "@mastra/core": "1.47.0",
32
32
  "@mastra/mcp": "1.12.0"
33
33
  },
@@ -45,7 +45,7 @@
45
45
  "./package.json": "./package.json"
46
46
  }
47
47
  },
48
- "version": "0.6.113",
48
+ "version": "0.6.114",
49
49
  "types": "./lib/index.d.ts",
50
50
  "type": "module",
51
51
  "exports": {
package/src/config.ts CHANGED
@@ -11,6 +11,7 @@ export interface GraphitiPluginConfig extends BasePluginConfig {
11
11
  publicPort?: number;
12
12
  appPort?: number;
13
13
  graphitiPort?: number;
14
+ litellmPort?: number;
14
15
  routePrefix?: string;
15
16
  python?: string;
16
17
  journalNamespace?: string;
@@ -20,6 +21,7 @@ export interface ResolvedGraphitiPluginConfig extends GraphitiPluginConfig {
20
21
  publicPort: number;
21
22
  appPort: number;
22
23
  graphitiPort: number;
24
+ litellmPort: number;
23
25
  routePrefix: string;
24
26
  python: string;
25
27
  journalNamespace: string;
@@ -31,6 +33,7 @@ export const GRAPHITI_CONFIG_SCHEMA = {
31
33
  publicPort: { type: "integer", minimum: 1, maximum: 65535 },
32
34
  appPort: { type: "integer", minimum: 1, maximum: 65535 },
33
35
  graphitiPort: { type: "integer", minimum: 1, maximum: 65535 },
36
+ litellmPort: { type: "integer", minimum: 1, maximum: 65535 },
34
37
  routePrefix: { type: "string" },
35
38
  python: { type: "string" },
36
39
  journalNamespace: { type: "string" },
@@ -60,7 +63,9 @@ export function resolveGraphitiConfig(
60
63
  0,
61
64
  coreConfig.ENV_ONLY,
62
65
  );
63
- if (new Set([publicPort, appPort, graphitiPort]).size !== 3) {
66
+ const litellmPort = coreConfig.port(config.litellmPort, "LITELLM_PORT", 0, coreConfig.ENV_ONLY);
67
+ const configuredPorts = [publicPort, appPort, graphitiPort, litellmPort].filter(Boolean);
68
+ if (new Set(configuredPorts).size !== configuredPorts.length) {
64
69
  throw new ConfigurationError("Graphiti public, AppKit, and sidecar ports must be distinct");
65
70
  }
66
71
  const routePrefix = normalizeRoutePrefix(
@@ -79,6 +84,7 @@ export function resolveGraphitiConfig(
79
84
  publicPort,
80
85
  appPort,
81
86
  graphitiPort,
87
+ litellmPort,
82
88
  routePrefix,
83
89
  python,
84
90
  journalNamespace,
package/src/plugin.ts CHANGED
@@ -66,9 +66,13 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
66
66
 
67
67
  override async setup(): Promise<void> {
68
68
  const configured = resolveGraphitiConfig(this.config);
69
+ const graphitiPort = configured.graphitiPort || (await availablePort());
70
+ let litellmPort = configured.litellmPort || (await availablePort());
71
+ while (litellmPort === graphitiPort) litellmPort = await availablePort();
69
72
  this.resolved = {
70
73
  ...configured,
71
- graphitiPort: configured.graphitiPort || (await availablePort()),
74
+ graphitiPort,
75
+ litellmPort,
72
76
  };
73
77
  if (!process.env.LAKEBASE_ENDPOINT && !process.env.PGHOST) {
74
78
  throw new Error(
@@ -86,6 +90,9 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
86
90
  GRAPHITI_HOST: "127.0.0.1",
87
91
  GRAPHITI_PORT: String(this.resolved.graphitiPort),
88
92
  JOURNAL_NAMESPACE: this.resolved.journalNamespace,
93
+ LITELLM_HOST: "127.0.0.1",
94
+ LITELLM_PORT: String(this.resolved.litellmPort),
95
+ MANAGE_LITELLM: "true",
89
96
  },
90
97
  stdin: "ignore",
91
98
  stdout: "inherit",
@@ -133,6 +140,7 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
133
140
  this.logger.info("ready", {
134
141
  appPort: this.resolved.appPort,
135
142
  graphitiPort: this.resolved.graphitiPort,
143
+ litellmPort: this.resolved.litellmPort,
136
144
  publicPort: this.resolved.publicPort,
137
145
  mcpPath: `${this.resolved.routePrefix}/mcp/`,
138
146
  tools: Object.keys(this.mcpTools),
@@ -156,6 +164,7 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
156
164
  return {
157
165
  appPort: resolved.appPort,
158
166
  graphitiPort: resolved.graphitiPort,
167
+ litellmPort: resolved.litellmPort,
159
168
  mcpPath: `${resolved.routePrefix}/mcp/`,
160
169
  publicPort: resolved.publicPort,
161
170
  routePrefix: resolved.routePrefix,