@kalera/munin-sdk 0.1.0 → 1.0.1

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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @kalera/munin-sdk@0.1.0 build /home/runner/work/munin-for-agents/munin-for-agents/packages/ts-sdk
2
+ > @kalera/munin-sdk@1.0.1 build /home/runner/work/munin-for-agents/munin-for-agents/packages/ts-sdk
3
3
  > tsc -p tsconfig.json
4
4
 
package/dist/client.d.ts CHANGED
@@ -2,19 +2,24 @@ import type { MuninAction, MuninCapabilities, MuninClientConfig, MuninResponse }
2
2
  export declare class MuninClient {
3
3
  private readonly baseUrl;
4
4
  private readonly apiKey?;
5
- private readonly project;
6
5
  private readonly timeoutMs;
7
6
  private readonly fetchImpl;
8
7
  private capabilitiesCache?;
9
- constructor(config: MuninClientConfig);
8
+ constructor(config?: MuninClientConfig);
10
9
  capabilities(forceRefresh?: boolean): Promise<MuninCapabilities>;
11
- invoke<TPayload extends Record<string, unknown>, TData = unknown>(action: MuninAction, payload: TPayload, options?: {
10
+ invoke<TPayload extends Record<string, unknown>, TData = unknown>(projectId: string, action: MuninAction, payload: TPayload, options?: {
12
11
  requestId?: string;
13
12
  ensureCapability?: boolean;
14
13
  }): Promise<MuninResponse<TData>>;
15
- store(payload: Record<string, unknown>): Promise<MuninResponse<unknown>>;
16
- retrieve(payload: Record<string, unknown>): Promise<MuninResponse<unknown>>;
17
- search(payload: Record<string, unknown>): Promise<MuninResponse<unknown>>;
18
- list(payload?: Record<string, unknown>): Promise<MuninResponse<unknown>>;
19
- recent(payload?: Record<string, unknown>): Promise<MuninResponse<unknown>>;
14
+ /**
15
+ * Cleans up raw Munin response for LLM context efficiency.
16
+ * Removes dense vector arrays and formats GraphRAG objects into readable structures.
17
+ */
18
+ private formatLlmResponse;
19
+ private formatGraph;
20
+ store(projectId: string, payload: Record<string, unknown>): Promise<MuninResponse<unknown>>;
21
+ retrieve(projectId: string, payload: Record<string, unknown>): Promise<MuninResponse<unknown>>;
22
+ search(projectId: string, payload: Record<string, unknown>): Promise<MuninResponse<unknown>>;
23
+ list(projectId: string, payload?: Record<string, unknown>): Promise<MuninResponse<unknown>>;
24
+ recent(projectId: string, payload?: Record<string, unknown>): Promise<MuninResponse<unknown>>;
20
25
  }
package/dist/client.js CHANGED
@@ -4,16 +4,14 @@ const DEFAULT_TIMEOUT_MS = 15_000;
4
4
  export class MuninClient {
5
5
  baseUrl;
6
6
  apiKey;
7
- project;
8
7
  timeoutMs;
9
8
  fetchImpl;
10
9
  capabilitiesCache;
11
10
  constructor(config) {
12
- this.baseUrl = config.baseUrl.replace(/\/$/, "");
13
- this.apiKey = config.apiKey;
14
- this.project = config.project;
15
- this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
16
- this.fetchImpl = config.fetchImpl ?? fetch;
11
+ this.baseUrl = (config?.baseUrl || "https://munin.kalera.dev").replace(/\/$/, "");
12
+ this.apiKey = config?.apiKey;
13
+ this.timeoutMs = config?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
14
+ this.fetchImpl = config?.fetchImpl ?? fetch;
17
15
  }
18
16
  async capabilities(forceRefresh = false) {
19
17
  if (this.capabilitiesCache && !forceRefresh) {
@@ -23,7 +21,7 @@ export class MuninClient {
23
21
  this.capabilitiesCache = caps;
24
22
  return caps;
25
23
  }
26
- async invoke(action, payload, options) {
24
+ async invoke(projectId, action, payload, options) {
27
25
  if (options?.ensureCapability) {
28
26
  const caps = await this.capabilities();
29
27
  if (!isActionSupported(caps, action)) {
@@ -35,13 +33,14 @@ export class MuninClient {
35
33
  }
36
34
  const request = {
37
35
  apiKey: this.apiKey,
38
- projectId: this.project,
36
+ project: projectId,
37
+ projectId: projectId, // Fallback for un-restarted server
39
38
  action,
40
39
  payload,
41
40
  requestId: options?.requestId,
42
41
  client: {
43
42
  name: "@kalera/munin-sdk",
44
- version: "0.1.0",
43
+ version: "1.0.0",
45
44
  },
46
45
  };
47
46
  const controller = new AbortController();
@@ -59,26 +58,79 @@ export class MuninClient {
59
58
  clearTimeout(timeout);
60
59
  const body = (await response.json());
61
60
  if (!response.ok || (body.ok === false) || (body.success === false)) {
62
- throw new MuninSdkError(body.error ?? {
61
+ let errObj = body.error;
62
+ if (typeof errObj === 'string') {
63
+ errObj = { code: "INTERNAL_ERROR", message: errObj };
64
+ }
65
+ throw new MuninSdkError(errObj ?? {
63
66
  code: "INTERNAL_ERROR",
64
67
  message: `Unexpected failure invoking action '${action}'`,
65
68
  });
66
69
  }
67
- return body;
70
+ return this.formatLlmResponse(body);
71
+ }
72
+ /**
73
+ * Cleans up raw Munin response for LLM context efficiency.
74
+ * Removes dense vector arrays and formats GraphRAG objects into readable structures.
75
+ */
76
+ formatLlmResponse(rawRes) {
77
+ if (!rawRes || !rawRes.data)
78
+ return rawRes;
79
+ const data = rawRes.data;
80
+ // Clean single memory retrieve
81
+ if (data.key && data.content) {
82
+ if (data.embedding)
83
+ delete data.embedding;
84
+ if (data.knowledge_graph) {
85
+ data.knowledge_graph = this.formatGraph(data.knowledge_graph);
86
+ }
87
+ }
88
+ // Clean search/list/recent results
89
+ if (Array.isArray(data.results)) {
90
+ data.results = data.results.map((mem) => {
91
+ if (mem.embedding)
92
+ delete mem.embedding;
93
+ return mem;
94
+ });
95
+ }
96
+ // Clean graph in search
97
+ if (data.knowledge_graph) {
98
+ data.knowledge_graph = this.formatGraph(data.knowledge_graph);
99
+ }
100
+ return rawRes;
101
+ }
102
+ formatGraph(kg) {
103
+ if (!kg)
104
+ return kg;
105
+ const entities = (kg.entities || []).map((e) => {
106
+ if (e.embedding)
107
+ delete e.embedding;
108
+ return `${e.name} (${e.type}): ${e.description}`;
109
+ });
110
+ const relationships = (kg.relationships || []).map((r) => {
111
+ if (r.embedding)
112
+ delete r.embedding;
113
+ return `${r.source} -[${r.relation}]-> ${r.target}`;
114
+ });
115
+ return {
116
+ summary: "GraphRAG knowledge formatted for readability",
117
+ entities,
118
+ relationships
119
+ };
68
120
  }
69
- async store(payload) {
70
- return this.invoke("store", payload, { ensureCapability: true });
121
+ async store(projectId, payload) {
122
+ return this.invoke(projectId, "store", payload, { ensureCapability: true });
71
123
  }
72
- async retrieve(payload) {
73
- return this.invoke("retrieve", payload, { ensureCapability: true });
124
+ async retrieve(projectId, payload) {
125
+ return this.invoke(projectId, "retrieve", payload, { ensureCapability: true });
74
126
  }
75
- async search(payload) {
76
- return this.invoke("search", payload, { ensureCapability: true });
127
+ async search(projectId, payload) {
128
+ return this.invoke(projectId, "search", payload, { ensureCapability: true });
77
129
  }
78
- async list(payload = {}) {
79
- return this.invoke("list", payload, { ensureCapability: true });
130
+ async list(projectId, payload = {}) {
131
+ return this.invoke(projectId, "list", payload, { ensureCapability: true });
80
132
  }
81
- async recent(payload = {}) {
82
- return this.invoke("recent", payload, { ensureCapability: true });
133
+ async recent(projectId, payload = {}) {
134
+ return this.invoke(projectId, "recent", payload, { ensureCapability: true });
83
135
  }
84
136
  }
package/dist/types.d.ts CHANGED
@@ -37,9 +37,8 @@ export interface MuninResponse<TData = unknown> {
37
37
  requestId?: string;
38
38
  }
39
39
  export interface MuninClientConfig {
40
- baseUrl: string;
40
+ baseUrl?: string;
41
41
  apiKey?: string;
42
- project: string;
43
42
  timeoutMs?: number;
44
43
  fetchImpl?: typeof fetch;
45
44
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kalera/munin-sdk",
3
- "version": "0.1.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/client.ts CHANGED
@@ -16,17 +16,15 @@ const DEFAULT_TIMEOUT_MS = 15_000;
16
16
  export class MuninClient {
17
17
  private readonly baseUrl: string;
18
18
  private readonly apiKey?: string;
19
- private readonly project: string;
20
19
  private readonly timeoutMs: number;
21
20
  private readonly fetchImpl: typeof fetch;
22
21
  private capabilitiesCache?: MuninCapabilities;
23
22
 
24
- constructor(config: MuninClientConfig) {
25
- this.baseUrl = config.baseUrl.replace(/\/$/, "");
26
- this.apiKey = config.apiKey;
27
- this.project = config.project;
28
- this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
29
- this.fetchImpl = config.fetchImpl ?? fetch;
23
+ constructor(config?: MuninClientConfig) {
24
+ this.baseUrl = (config?.baseUrl || "https://munin.kalera.dev").replace(/\/$/, "");
25
+ this.apiKey = config?.apiKey;
26
+ this.timeoutMs = config?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
27
+ this.fetchImpl = config?.fetchImpl ?? fetch;
30
28
  }
31
29
 
32
30
  async capabilities(forceRefresh = false): Promise<MuninCapabilities> {
@@ -44,6 +42,7 @@ export class MuninClient {
44
42
  }
45
43
 
46
44
  async invoke<TPayload extends Record<string, unknown>, TData = unknown>(
45
+ projectId: string,
47
46
  action: MuninAction,
48
47
  payload: TPayload,
49
48
  options?: { requestId?: string; ensureCapability?: boolean },
@@ -60,13 +59,14 @@ export class MuninClient {
60
59
 
61
60
  const request = {
62
61
  apiKey: this.apiKey,
63
- projectId: this.project,
62
+ project: projectId,
63
+ projectId: projectId, // Fallback for un-restarted server
64
64
  action,
65
65
  payload,
66
66
  requestId: options?.requestId,
67
67
  client: {
68
68
  name: "@kalera/munin-sdk",
69
- version: "0.1.0",
69
+ version: "1.0.0",
70
70
  },
71
71
  };
72
72
 
@@ -91,34 +91,92 @@ export class MuninClient {
91
91
  const body = (await response.json()) as any;
92
92
 
93
93
  if (!response.ok || (body.ok === false) || (body.success === false)) {
94
+ let errObj = body.error;
95
+ if (typeof errObj === 'string') {
96
+ errObj = { code: "INTERNAL_ERROR", message: errObj };
97
+ }
98
+
94
99
  throw new MuninSdkError(
95
- body.error ?? {
100
+ errObj ?? {
96
101
  code: "INTERNAL_ERROR",
97
102
  message: `Unexpected failure invoking action '${action}'`,
98
103
  },
99
104
  );
100
105
  }
101
106
 
102
- return body;
107
+ return this.formatLlmResponse(body);
108
+ }
109
+
110
+ /**
111
+ * Cleans up raw Munin response for LLM context efficiency.
112
+ * Removes dense vector arrays and formats GraphRAG objects into readable structures.
113
+ */
114
+ private formatLlmResponse(rawRes: any): any {
115
+ if (!rawRes || !rawRes.data) return rawRes;
116
+
117
+ const data = rawRes.data;
118
+
119
+ // Clean single memory retrieve
120
+ if (data.key && data.content) {
121
+ if (data.embedding) delete data.embedding;
122
+ if (data.knowledge_graph) {
123
+ data.knowledge_graph = this.formatGraph(data.knowledge_graph);
124
+ }
125
+ }
126
+
127
+ // Clean search/list/recent results
128
+ if (Array.isArray(data.results)) {
129
+ data.results = data.results.map((mem: any) => {
130
+ if (mem.embedding) delete mem.embedding;
131
+ return mem;
132
+ });
133
+ }
134
+
135
+ // Clean graph in search
136
+ if (data.knowledge_graph) {
137
+ data.knowledge_graph = this.formatGraph(data.knowledge_graph);
138
+ }
139
+
140
+ return rawRes;
141
+ }
142
+
143
+ private formatGraph(kg: any): any {
144
+ if (!kg) return kg;
145
+
146
+ const entities = (kg.entities || []).map((e: any) => {
147
+ if (e.embedding) delete e.embedding;
148
+ return `${e.name} (${e.type}): ${e.description}`;
149
+ });
150
+
151
+ const relationships = (kg.relationships || []).map((r: any) => {
152
+ if (r.embedding) delete r.embedding;
153
+ return `${r.source} -[${r.relation}]-> ${r.target}`;
154
+ });
155
+
156
+ return {
157
+ summary: "GraphRAG knowledge formatted for readability",
158
+ entities,
159
+ relationships
160
+ };
103
161
  }
104
162
 
105
- async store(payload: Record<string, unknown>) {
106
- return this.invoke("store", payload, { ensureCapability: true });
163
+ async store(projectId: string, payload: Record<string, unknown>) {
164
+ return this.invoke(projectId, "store", payload, { ensureCapability: true });
107
165
  }
108
166
 
109
- async retrieve(payload: Record<string, unknown>) {
110
- return this.invoke("retrieve", payload, { ensureCapability: true });
167
+ async retrieve(projectId: string, payload: Record<string, unknown>) {
168
+ return this.invoke(projectId, "retrieve", payload, { ensureCapability: true });
111
169
  }
112
170
 
113
- async search(payload: Record<string, unknown>) {
114
- return this.invoke("search", payload, { ensureCapability: true });
171
+ async search(projectId: string, payload: Record<string, unknown>) {
172
+ return this.invoke(projectId, "search", payload, { ensureCapability: true });
115
173
  }
116
174
 
117
- async list(payload: Record<string, unknown> = {}) {
118
- return this.invoke("list", payload, { ensureCapability: true });
175
+ async list(projectId: string, payload: Record<string, unknown> = {}) {
176
+ return this.invoke(projectId, "list", payload, { ensureCapability: true });
119
177
  }
120
178
 
121
- async recent(payload: Record<string, unknown> = {}) {
122
- return this.invoke("recent", payload, { ensureCapability: true });
179
+ async recent(projectId: string, payload: Record<string, unknown> = {}) {
180
+ return this.invoke(projectId, "recent", payload, { ensureCapability: true });
123
181
  }
124
182
  }
package/src/types.ts CHANGED
@@ -55,9 +55,8 @@ export interface MuninResponse<TData = unknown> {
55
55
  }
56
56
 
57
57
  export interface MuninClientConfig {
58
- baseUrl: string;
58
+ baseUrl?: string;
59
59
  apiKey?: string;
60
- project: string;
61
60
  timeoutMs?: number;
62
61
  fetchImpl?: typeof fetch;
63
62
  }
@@ -47,14 +47,13 @@ async function run() {
47
47
 
48
48
  const client = new MuninClient({
49
49
  baseUrl: "http://localhost:4000",
50
- project: "default",
51
50
  fetchImpl: fakeFetch,
52
51
  });
53
52
 
54
53
  const capabilities = await client.capabilities();
55
54
  assert.equal(capabilities.specVersion, "v1.0.0");
56
55
 
57
- const result = await client.store({ key: "hello", content: "world" });
56
+ const result = await client.store("default", { key: "hello", content: "world" });
58
57
  assert.equal(result.ok, true);
59
58
  assert.equal((result.data as any).echoedAction, "store");
60
59