@marshmallo/marlo 0.1.2 → 0.1.3
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 +6 -8
- package/dist/index.d.mts +2 -3
- package/dist/index.d.ts +2 -3
- package/dist/index.js +17 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +17 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
# @marshmallo/marlo
|
|
2
2
|
|
|
3
|
-
The official TypeScript SDK for
|
|
3
|
+
The official TypeScript SDK for Marlo - the open-source agent learning platform.
|
|
4
4
|
|
|
5
5
|
Marlo enables AI agents to learn and improve autonomously in production. It captures agent behavior, evaluates outcomes, and turns failures into actionable learnings.
|
|
6
6
|
|
|
7
|
-
[](https://www.npmjs.com/package/@marshmallo/marlo)
|
|
8
7
|
[](https://opensource.org/licenses/MIT)
|
|
9
8
|
|
|
10
9
|
## Installation
|
|
@@ -18,8 +17,8 @@ npm install @marshmallo/marlo
|
|
|
18
17
|
```typescript
|
|
19
18
|
import * as marlo from '@marshmallo/marlo';
|
|
20
19
|
|
|
21
|
-
// Initialize
|
|
22
|
-
await marlo.init(
|
|
20
|
+
// Initialize (connects to local server at http://localhost:8000 by default)
|
|
21
|
+
await marlo.init();
|
|
23
22
|
|
|
24
23
|
// Register your agent
|
|
25
24
|
marlo.agent('support-bot', 'You are a customer support agent.', [
|
|
@@ -53,7 +52,8 @@ Agents fail silently in production. The same mistakes repeat because failures ar
|
|
|
53
52
|
### Initialize
|
|
54
53
|
|
|
55
54
|
```typescript
|
|
56
|
-
await marlo.init(
|
|
55
|
+
await marlo.init();
|
|
56
|
+
await marlo.init('http://localhost:8000');
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
### Register Agent
|
|
@@ -122,7 +122,7 @@ await marlo.shutdown();
|
|
|
122
122
|
```typescript
|
|
123
123
|
import * as marlo from '@marshmallo/marlo';
|
|
124
124
|
|
|
125
|
-
await marlo.init(
|
|
125
|
+
await marlo.init();
|
|
126
126
|
|
|
127
127
|
marlo.agent('support-bot', 'You are a customer support agent.', [
|
|
128
128
|
{ name: 'lookup_order', description: 'Find order by ID' }
|
|
@@ -164,8 +164,6 @@ async function handleMessage(input: string, threadId: string) {
|
|
|
164
164
|
|
|
165
165
|
## Links
|
|
166
166
|
|
|
167
|
-
- [Documentation](https://docs.marshmallo.ai)
|
|
168
|
-
- [Dashboard](https://marshmallo.ai)
|
|
169
167
|
- [Python SDK](https://pypi.org/project/marlo-sdk)
|
|
170
168
|
|
|
171
169
|
## License
|
package/dist/index.d.mts
CHANGED
|
@@ -49,18 +49,17 @@ interface LlmCallParams {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
declare class MarloClient {
|
|
52
|
-
private readonly apiKey;
|
|
53
52
|
private readonly endpoint;
|
|
54
53
|
private readonly _scope;
|
|
55
54
|
private readonly sender;
|
|
56
|
-
constructor(
|
|
55
|
+
constructor(endpoint: string, scope: Scope);
|
|
57
56
|
get scope(): Scope;
|
|
58
57
|
sendEvents(events: Event[]): void;
|
|
59
58
|
flush(): Promise<void>;
|
|
60
59
|
shutdown(): Promise<void>;
|
|
61
60
|
fetchLearnings(learningKey: string): Promise<LearningState | null>;
|
|
62
61
|
}
|
|
63
|
-
declare function init(
|
|
62
|
+
declare function init(endpoint?: string): Promise<void>;
|
|
64
63
|
declare function getClient(): MarloClient | null;
|
|
65
64
|
declare function isEnabled(): boolean;
|
|
66
65
|
declare function shutdown(): Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -49,18 +49,17 @@ interface LlmCallParams {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
declare class MarloClient {
|
|
52
|
-
private readonly apiKey;
|
|
53
52
|
private readonly endpoint;
|
|
54
53
|
private readonly _scope;
|
|
55
54
|
private readonly sender;
|
|
56
|
-
constructor(
|
|
55
|
+
constructor(endpoint: string, scope: Scope);
|
|
57
56
|
get scope(): Scope;
|
|
58
57
|
sendEvents(events: Event[]): void;
|
|
59
58
|
flush(): Promise<void>;
|
|
60
59
|
shutdown(): Promise<void>;
|
|
61
60
|
fetchLearnings(learningKey: string): Promise<LearningState | null>;
|
|
62
61
|
}
|
|
63
|
-
declare function init(
|
|
62
|
+
declare function init(endpoint?: string): Promise<void>;
|
|
64
63
|
declare function getClient(): MarloClient | null;
|
|
65
64
|
declare function isEnabled(): boolean;
|
|
66
65
|
declare function shutdown(): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -53,7 +53,6 @@ var BufferedEventSender = class {
|
|
|
53
53
|
this.flushTimer = null;
|
|
54
54
|
this.isShutdown = false;
|
|
55
55
|
this.eventsUrl = config.eventsUrl;
|
|
56
|
-
this.headers = { Authorization: `Bearer ${config.apiKey}` };
|
|
57
56
|
this.batchSize = Math.max(1, config.batchSize ?? DEFAULT_BATCH_SIZE);
|
|
58
57
|
this.flushIntervalMs = Math.max(
|
|
59
58
|
100,
|
|
@@ -116,7 +115,6 @@ var BufferedEventSender = class {
|
|
|
116
115
|
const response = await fetch(this.eventsUrl, {
|
|
117
116
|
method: "POST",
|
|
118
117
|
headers: {
|
|
119
|
-
...this.headers,
|
|
120
118
|
"Content-Type": "application/json"
|
|
121
119
|
},
|
|
122
120
|
body: JSON.stringify(batch),
|
|
@@ -144,8 +142,13 @@ var BufferedEventSender = class {
|
|
|
144
142
|
};
|
|
145
143
|
|
|
146
144
|
// src/client.ts
|
|
147
|
-
var DEFAULT_ENDPOINT = "
|
|
145
|
+
var DEFAULT_ENDPOINT = "http://localhost:8000";
|
|
148
146
|
var DEFAULT_TIMEOUT_MS2 = 5e3;
|
|
147
|
+
var LOCAL_SCOPE = {
|
|
148
|
+
project_id: "local",
|
|
149
|
+
org_id: "local",
|
|
150
|
+
user_id: "local"
|
|
151
|
+
};
|
|
149
152
|
function warn2(message) {
|
|
150
153
|
console.warn(`[marlo] ${message}`);
|
|
151
154
|
}
|
|
@@ -155,13 +158,11 @@ function info(message) {
|
|
|
155
158
|
var _client = null;
|
|
156
159
|
var _enabled = false;
|
|
157
160
|
var MarloClient = class {
|
|
158
|
-
constructor(
|
|
159
|
-
this.apiKey = apiKey;
|
|
161
|
+
constructor(endpoint, scope) {
|
|
160
162
|
this.endpoint = endpoint.replace(/\/+$/, "");
|
|
161
163
|
this._scope = scope;
|
|
162
164
|
this.sender = new BufferedEventSender({
|
|
163
|
-
eventsUrl: `${this.endpoint}/events
|
|
164
|
-
apiKey
|
|
165
|
+
eventsUrl: `${this.endpoint}/events`
|
|
165
166
|
});
|
|
166
167
|
}
|
|
167
168
|
get scope() {
|
|
@@ -183,7 +184,6 @@ var MarloClient = class {
|
|
|
183
184
|
const response = await fetch(`${this.endpoint}/learnings`, {
|
|
184
185
|
method: "POST",
|
|
185
186
|
headers: {
|
|
186
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
187
187
|
"Content-Type": "application/json"
|
|
188
188
|
},
|
|
189
189
|
body: JSON.stringify({ learning_key: learningKey }),
|
|
@@ -205,49 +205,15 @@ var MarloClient = class {
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
};
|
|
208
|
-
async function init(
|
|
209
|
-
const normalizedEndpoint = endpoint.replace(/\/+$/, "");
|
|
210
|
-
const scopeUrl = `${normalizedEndpoint}/scope`;
|
|
208
|
+
async function init(endpoint = DEFAULT_ENDPOINT) {
|
|
211
209
|
try {
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
const response = await fetch(scopeUrl, {
|
|
215
|
-
headers: { Authorization: `Bearer ${apiKey}` },
|
|
216
|
-
signal: controller.signal
|
|
217
|
-
});
|
|
218
|
-
clearTimeout(timeoutId);
|
|
219
|
-
if (response.status !== 200) {
|
|
220
|
-
warn2(`Marlo init failed: scope request returned ${response.status}`);
|
|
221
|
-
_enabled = false;
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
const payload = await response.json();
|
|
225
|
-
const scopeData = payload.scope ?? {};
|
|
226
|
-
const projectId = scopeData.project_id;
|
|
227
|
-
const orgId = scopeData.org_id;
|
|
228
|
-
const userId = scopeData.user_id;
|
|
229
|
-
if (typeof projectId !== "string" || !projectId.trim() || typeof orgId !== "string" || !orgId.trim() || typeof userId !== "string" || !userId.trim()) {
|
|
230
|
-
warn2("Marlo init failed: invalid scope response");
|
|
231
|
-
_enabled = false;
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
const scope = {
|
|
235
|
-
project_id: projectId.trim(),
|
|
236
|
-
org_id: orgId.trim(),
|
|
237
|
-
user_id: userId.trim()
|
|
238
|
-
};
|
|
239
|
-
_client = new MarloClient(apiKey, normalizedEndpoint, scope);
|
|
210
|
+
const normalizedEndpoint = endpoint.replace(/\/+$/, "");
|
|
211
|
+
_client = new MarloClient(normalizedEndpoint, LOCAL_SCOPE);
|
|
240
212
|
_enabled = true;
|
|
241
|
-
info(`Marlo SDK initialized
|
|
213
|
+
info(`Marlo SDK initialized (local mode)`);
|
|
242
214
|
} catch (error) {
|
|
243
215
|
if (error instanceof Error) {
|
|
244
|
-
|
|
245
|
-
warn2("Marlo init failed: timeout");
|
|
246
|
-
} else if (error.message.includes("ECONNREFUSED") || error.message.includes("fetch failed")) {
|
|
247
|
-
warn2("Marlo init failed: connection error");
|
|
248
|
-
} else {
|
|
249
|
-
warn2(`Marlo init failed: ${error.message}`);
|
|
250
|
-
}
|
|
216
|
+
warn2(`Marlo init failed: ${error.message}`);
|
|
251
217
|
} else {
|
|
252
218
|
warn2("Marlo init failed");
|
|
253
219
|
}
|
|
@@ -289,7 +255,7 @@ function sortObject(value) {
|
|
|
289
255
|
}
|
|
290
256
|
function jsonDigest(payload) {
|
|
291
257
|
const sorted = sortObject(payload);
|
|
292
|
-
const encoded = JSON.stringify(sorted);
|
|
258
|
+
const encoded = JSON.stringify(sorted) ?? "undefined";
|
|
293
259
|
return (0, import_crypto.createHash)("sha256").update(encoded, "utf-8").digest("hex");
|
|
294
260
|
}
|
|
295
261
|
|
|
@@ -301,6 +267,7 @@ var MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1;
|
|
|
301
267
|
var MAX_SEQUENCE = (1 << SEQUENCE_BITS) - 1;
|
|
302
268
|
var WORKER_ID_SHIFT = SEQUENCE_BITS;
|
|
303
269
|
var TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
|
|
270
|
+
var SAFE_INT_MASK = BigInt(Number.MAX_SAFE_INTEGER);
|
|
304
271
|
function parseWorkerId() {
|
|
305
272
|
const raw = (process.env.MARLO_WORKER_ID ?? "0").trim();
|
|
306
273
|
if (!raw) {
|
|
@@ -332,7 +299,8 @@ var IdGenerator = class {
|
|
|
332
299
|
this.sequence = 0;
|
|
333
300
|
}
|
|
334
301
|
this.lastTs = ts;
|
|
335
|
-
|
|
302
|
+
const raw = BigInt(ts - ID_EPOCH_MS) << BigInt(TIMESTAMP_SHIFT) | BigInt(WORKER_ID) << BigInt(WORKER_ID_SHIFT) | BigInt(this.sequence);
|
|
303
|
+
return Number(raw & SAFE_INT_MASK);
|
|
336
304
|
}
|
|
337
305
|
waitUntil(targetMs) {
|
|
338
306
|
let ts = Date.now();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/buffered-sender.ts","../src/client.ts","../src/digest.ts","../src/ids.ts","../src/registry.ts","../src/context.ts"],"sourcesContent":["export { init, shutdown, getClient, isEnabled, MarloClient } from './client';\nexport { task, TaskContext } from './context';\nexport { registerAgent, registerAgent as agent, getAgent } from './registry';\nexport { generateId } from './ids';\nexport { jsonDigest } from './digest';\nexport type {\n Scope,\n AgentDefinition,\n Event,\n LearningState,\n ToolDefinition,\n McpDefinition,\n ModelConfig,\n TokenUsage,\n LlmCallParams,\n} from './types';\n","import type { Event } from './types';\n\nconst DEFAULT_BATCH_SIZE = 50;\nconst DEFAULT_FLUSH_INTERVAL_MS = 1000;\nconst DEFAULT_RETRIES = 3;\nconst DEFAULT_RETRY_BACKOFF_MS = 500;\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport interface BufferedEventSenderConfig {\n eventsUrl: string;\n apiKey: string;\n batchSize?: number;\n flushIntervalMs?: number;\n maxRetries?: number;\n retryBackoffMs?: number;\n}\n\nexport class BufferedEventSender {\n private readonly eventsUrl: string;\n private readonly headers: Record<string, string>;\n private readonly batchSize: number;\n private readonly flushIntervalMs: number;\n private readonly maxRetries: number;\n private readonly retryBackoffMs: number;\n private queue: Event[] = [];\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private isShutdown = false;\n\n constructor(config: BufferedEventSenderConfig) {\n this.eventsUrl = config.eventsUrl;\n this.headers = { Authorization: `Bearer ${config.apiKey}` };\n this.batchSize = Math.max(1, config.batchSize ?? DEFAULT_BATCH_SIZE);\n this.flushIntervalMs = Math.max(\n 100,\n config.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS\n );\n this.maxRetries = Math.max(1, config.maxRetries ?? DEFAULT_RETRIES);\n this.retryBackoffMs = Math.max(\n 100,\n config.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS\n );\n\n this.flushTimer = setInterval(() => {\n this.flushAsync().catch(() => {});\n }, this.flushIntervalMs);\n }\n\n enqueue(events: Event[]): void {\n if (!events.length || this.isShutdown) {\n return;\n }\n this.queue.push(...events);\n if (this.queue.length >= this.batchSize) {\n this.flushAsync().catch(() => {});\n }\n }\n\n async flush(): Promise<void> {\n await this.flushAsync();\n }\n\n async shutdown(): Promise<void> {\n this.isShutdown = true;\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushAsync();\n }\n\n private async flushAsync(): Promise<void> {\n while (this.queue.length > 0) {\n const batch = this.queue.splice(0, this.batchSize);\n const success = await this.sendWithRetry(batch);\n if (!success) {\n this.queue.unshift(...batch);\n return;\n }\n }\n }\n\n private async sendWithRetry(batch: Event[]): Promise<boolean> {\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n if (await this.sendBatch(batch)) {\n return true;\n }\n await sleep(this.retryBackoffMs * 2 ** attempt);\n }\n return false;\n }\n\n private async sendBatch(batch: Event[]): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(this.eventsUrl, {\n method: 'POST',\n headers: {\n ...this.headers,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(batch),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status >= 200 && response.status < 300) {\n return true;\n }\n warn(`Event send returned ${response.status}`);\n return false;\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n warn('Event send timed out');\n } else {\n warn(`Event send failed: ${error.message}`);\n }\n } else {\n warn('Event send failed');\n }\n return false;\n }\n }\n}\n","import { BufferedEventSender } from './buffered-sender';\nimport type { Event, LearningState, Scope } from './types';\n\nconst DEFAULT_ENDPOINT = 'https://marlo.marshmallo.ai';\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction info(message: string): void {\n console.info(`[marlo] ${message}`);\n}\n\nlet _client: MarloClient | null = null;\nlet _enabled = false;\n\nexport class MarloClient {\n private readonly apiKey: string;\n private readonly endpoint: string;\n private readonly _scope: Scope;\n private readonly sender: BufferedEventSender;\n\n constructor(apiKey: string, endpoint: string, scope: Scope) {\n this.apiKey = apiKey;\n this.endpoint = endpoint.replace(/\\/+$/, '');\n this._scope = scope;\n this.sender = new BufferedEventSender({\n eventsUrl: `${this.endpoint}/events`,\n apiKey,\n });\n }\n\n get scope(): Scope {\n return this._scope;\n }\n\n sendEvents(events: Event[]): void {\n this.sender.enqueue(events);\n }\n\n async flush(): Promise<void> {\n await this.sender.flush();\n }\n\n async shutdown(): Promise<void> {\n await this.sender.shutdown();\n }\n\n async fetchLearnings(learningKey: string): Promise<LearningState | null> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(`${this.endpoint}/learnings`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ learning_key: learningKey }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status < 200 || response.status >= 300) {\n return null;\n }\n\n const data = await response.json();\n return data.learning_state ?? null;\n } catch (error) {\n if (error instanceof Error) {\n warn(`Fetch learnings failed: ${error.message}`);\n } else {\n warn('Fetch learnings failed');\n }\n return null;\n }\n }\n}\n\nexport async function init(\n apiKey: string,\n endpoint: string = DEFAULT_ENDPOINT\n): Promise<void> {\n const normalizedEndpoint = endpoint.replace(/\\/+$/, '');\n const scopeUrl = `${normalizedEndpoint}/scope`;\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(scopeUrl, {\n headers: { Authorization: `Bearer ${apiKey}` },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status !== 200) {\n warn(`Marlo init failed: scope request returned ${response.status}`);\n _enabled = false;\n return;\n }\n\n const payload = await response.json();\n const scopeData = payload.scope ?? {};\n const projectId = scopeData.project_id;\n const orgId = scopeData.org_id;\n const userId = scopeData.user_id;\n\n if (\n typeof projectId !== 'string' ||\n !projectId.trim() ||\n typeof orgId !== 'string' ||\n !orgId.trim() ||\n typeof userId !== 'string' ||\n !userId.trim()\n ) {\n warn('Marlo init failed: invalid scope response');\n _enabled = false;\n return;\n }\n\n const scope: Scope = {\n project_id: projectId.trim(),\n org_id: orgId.trim(),\n user_id: userId.trim(),\n };\n\n _client = new MarloClient(apiKey, normalizedEndpoint, scope);\n _enabled = true;\n info(`Marlo SDK initialized for project ${projectId}`);\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n warn('Marlo init failed: timeout');\n } else if (\n error.message.includes('ECONNREFUSED') ||\n error.message.includes('fetch failed')\n ) {\n warn('Marlo init failed: connection error');\n } else {\n warn(`Marlo init failed: ${error.message}`);\n }\n } else {\n warn('Marlo init failed');\n }\n _enabled = false;\n }\n}\n\nexport function getClient(): MarloClient | null {\n return _client;\n}\n\nexport function isEnabled(): boolean {\n return _enabled;\n}\n\nexport async function shutdown(): Promise<void> {\n if (_client) {\n await _client.shutdown();\n _client = null;\n }\n _enabled = false;\n}\n","import { createHash } from 'crypto';\n\nfunction sortObject(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map(sortObject);\n }\n if (typeof value === 'object') {\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(value as Record<string, unknown>).sort();\n for (const key of keys) {\n sorted[key] = sortObject((value as Record<string, unknown>)[key]);\n }\n return sorted;\n }\n return value;\n}\n\nexport function jsonDigest(payload: unknown): string {\n const sorted = sortObject(payload);\n const encoded = JSON.stringify(sorted);\n return createHash('sha256').update(encoded, 'utf-8').digest('hex');\n}\n","const ID_EPOCH_MS = 1700000000000;\nconst WORKER_ID_BITS = 10;\nconst SEQUENCE_BITS = 12;\nconst MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1;\nconst MAX_SEQUENCE = (1 << SEQUENCE_BITS) - 1;\nconst WORKER_ID_SHIFT = SEQUENCE_BITS;\nconst TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;\n\nfunction parseWorkerId(): number {\n const raw = (process.env.MARLO_WORKER_ID ?? '0').trim();\n if (!raw) {\n return 0;\n }\n const workerId = parseInt(raw, 10);\n if (isNaN(workerId) || workerId < 0 || workerId > MAX_WORKER_ID) {\n return 0;\n }\n return workerId;\n}\n\nconst WORKER_ID = parseWorkerId();\n\nclass IdGenerator {\n private lastTs = 0;\n private sequence = 0;\n\n nextId(): number {\n let ts = Date.now();\n\n if (ts < this.lastTs) {\n ts = this.waitUntil(this.lastTs);\n }\n\n if (ts === this.lastTs) {\n this.sequence = (this.sequence + 1) & MAX_SEQUENCE;\n if (this.sequence === 0) {\n ts = this.waitUntil(this.lastTs + 1);\n }\n } else {\n this.sequence = 0;\n }\n\n this.lastTs = ts;\n return (\n ((ts - ID_EPOCH_MS) << TIMESTAMP_SHIFT) |\n (WORKER_ID << WORKER_ID_SHIFT) |\n this.sequence\n );\n }\n\n private waitUntil(targetMs: number): number {\n let ts = Date.now();\n while (ts < targetMs) {\n ts = Date.now();\n }\n return ts;\n }\n}\n\nconst idGenerator = new IdGenerator();\n\nexport function generateId(): number {\n return idGenerator.nextId();\n}\n","import { jsonDigest } from './digest';\nimport type {\n AgentDefinition,\n ToolDefinition,\n McpDefinition,\n ModelConfig,\n} from './types';\n\nclass AgentRegistry {\n private agents: Map<string, AgentDefinition> = new Map();\n\n register(definition: AgentDefinition): void {\n const existing = this.agents.get(definition.name);\n if (!existing) {\n this.agents.set(definition.name, definition);\n } else if (existing.definition_hash !== definition.definition_hash) {\n definition.sent = false;\n this.agents.set(definition.name, definition);\n } else {\n definition.sent = existing.sent;\n this.agents.set(definition.name, definition);\n }\n }\n\n get(name: string): AgentDefinition | null {\n return this.agents.get(name) ?? null;\n }\n\n markSent(name: string): void {\n const agent = this.agents.get(name);\n if (agent) {\n agent.sent = true;\n }\n }\n\n needsResend(name: string): boolean {\n const agent = this.agents.get(name);\n return agent !== null && agent !== undefined && !agent.sent;\n }\n}\n\nlet registry: AgentRegistry | null = null;\n\nfunction getRegistry(): AgentRegistry {\n if (!registry) {\n registry = new AgentRegistry();\n }\n return registry;\n}\n\nexport function registerAgent(\n name: string,\n systemPrompt: string,\n tools: ToolDefinition[],\n mcp?: McpDefinition[] | null,\n modelConfig?: ModelConfig | null\n): string {\n const definitionHash = jsonDigest({\n name,\n system_prompt: systemPrompt,\n tool_definitions: tools,\n mcp_definitions: mcp ?? null,\n model_config: modelConfig ?? null,\n });\n\n const definition: AgentDefinition = {\n name,\n system_prompt: systemPrompt,\n tools,\n mcp: mcp ?? null,\n model_config: modelConfig ?? null,\n definition_hash: definitionHash,\n sent: false,\n };\n\n getRegistry().register(definition);\n return definitionHash;\n}\n\nexport function getAgent(name: string): AgentDefinition | null {\n return getRegistry().get(name);\n}\n\nexport function markAgentSent(name: string): void {\n getRegistry().markSent(name);\n}\n\nexport function needsResend(name: string): boolean {\n return getRegistry().needsResend(name);\n}\n","import { getClient, isEnabled } from './client';\nimport { jsonDigest } from './digest';\nimport { generateId } from './ids';\nimport { getAgent, markAgentSent, needsResend } from './registry';\nimport type { Event, LearningState, LlmCallParams } from './types';\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction generateInvocationId(): string {\n return crypto.randomUUID();\n}\n\nfunction computeSessionId(projectId: string, threadId: string): number {\n const digest = jsonDigest(`${projectId}:${threadId}`);\n return parseInt(digest.slice(0, 16), 16);\n}\n\nexport function task(\n threadId: string,\n agent: string,\n threadName?: string\n): TaskContext {\n return new TaskContext(threadId, agent, threadName);\n}\n\nexport class TaskContext {\n private readonly threadId: string;\n private readonly agentName: string;\n private readonly threadName: string | undefined;\n private readonly parent: TaskContext | undefined;\n private taskId: number | null = null;\n private sessionId: number | null = null;\n private invocationId: string | null = null;\n private inputText: string | null = null;\n private outputText: string | null = null;\n private errorMessage: string | null = null;\n private events: Event[] = [];\n\n constructor(\n threadId: string,\n agent: string,\n threadName?: string,\n parent?: TaskContext\n ) {\n this.threadId = threadId;\n this.agentName = agent;\n this.threadName = threadName;\n this.parent = parent;\n }\n\n start(): this {\n try {\n const client = getClient();\n const projectId = client?.scope.project_id ?? '';\n this.sessionId = computeSessionId(projectId, this.threadId);\n this.taskId = generateId();\n this.invocationId = generateInvocationId();\n\n if (needsResend(this.agentName)) {\n const agentDef = getAgent(this.agentName);\n if (agentDef) {\n this.emit('agent_definition', {\n name: agentDef.name,\n system_prompt: agentDef.system_prompt,\n tool_definitions: agentDef.tools,\n mcp_definitions: agentDef.mcp,\n model_config: agentDef.model_config,\n definition_hash: agentDef.definition_hash,\n });\n markAgentSent(this.agentName);\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext start failed: ${error.message}`);\n } else {\n warn('TaskContext start failed');\n }\n }\n return this;\n }\n\n end(hasError?: boolean): void {\n try {\n const status =\n hasError || this.errorMessage !== null ? 'error' : 'success';\n const payload: Record<string, unknown> = { status };\n if (this.outputText !== null) {\n payload.final_answer = this.outputText;\n }\n if (this.errorMessage !== null) {\n payload.error = this.errorMessage;\n }\n this.emit('task_end', payload);\n this.flush();\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext end failed: ${error.message}`);\n } else {\n warn('TaskContext end failed');\n }\n }\n }\n\n input(text: string): void {\n try {\n this.inputText = text;\n const metadata: Record<string, unknown> = { thread_id: this.threadId };\n if (this.threadName !== undefined) {\n metadata.thread_name = this.threadName;\n }\n this.emit('task_start', { task: text, metadata });\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext input failed: ${error.message}`);\n } else {\n warn('TaskContext input failed');\n }\n }\n }\n\n output(text: string): void {\n try {\n this.outputText = text;\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext output failed: ${error.message}`);\n } else {\n warn('TaskContext output failed');\n }\n }\n }\n\n tool(\n name: string,\n input: Record<string, unknown>,\n output: unknown,\n error?: string\n ): void {\n try {\n const payload: Record<string, unknown> = {\n tool_name: name,\n input,\n output,\n };\n if (error !== undefined) {\n payload.error = error;\n }\n this.emit('tool_call', payload);\n } catch (err) {\n if (err instanceof Error) {\n warn(`TaskContext tool failed: ${err.message}`);\n } else {\n warn('TaskContext tool failed');\n }\n }\n }\n\n reasoning(text: string): void {\n try {\n this.emit('log', { reasoning: text });\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext reasoning failed: ${error.message}`);\n } else {\n warn('TaskContext reasoning failed');\n }\n }\n }\n\n llm(params: LlmCallParams): void {\n try {\n if (params.messages === undefined) {\n warn('llm() called without messages');\n }\n if (params.response === undefined) {\n warn('llm() called without response');\n }\n\n const payload: Record<string, unknown> = {\n model: params.model,\n usage: params.usage,\n };\n if (params.messages !== undefined) {\n payload.messages = params.messages;\n }\n if (params.response !== undefined) {\n payload.response = params.response;\n }\n this.emit('llm_call', payload);\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext llm failed: ${error.message}`);\n } else {\n warn('TaskContext llm failed');\n }\n }\n }\n\n error(message: string): void {\n try {\n this.errorMessage = message;\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext error failed: ${error.message}`);\n } else {\n warn('TaskContext error failed');\n }\n }\n }\n\n child(agent: string): TaskContext {\n return new TaskContext(this.threadId, agent, this.threadName, this);\n }\n\n async getLearnings(): Promise<LearningState | null> {\n try {\n const client = getClient();\n if (!client) {\n return null;\n }\n return await client.fetchLearnings(this.agentName);\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext getLearnings failed: ${error.message}`);\n } else {\n warn('TaskContext getLearnings failed');\n }\n return null;\n }\n }\n\n private emit(eventType: string, payload: Record<string, unknown>): void {\n const agentDef = getAgent(this.agentName);\n const agentId = agentDef?.name ?? this.agentName;\n const parentAgentId = this.parent?.agentName ?? null;\n\n const event: Event = {\n run_id: this.sessionId,\n agent_id: agentId,\n parent_agent_id: parentAgentId,\n invocation_id: this.invocationId,\n task_id: this.taskId,\n event_type: eventType,\n payload,\n };\n this.events.push(event);\n }\n\n private flush(): void {\n const client = getClient();\n if (!client || !isEnabled()) {\n this.events = [];\n return;\n }\n try {\n client.sendEvents(this.events);\n client.flush();\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext flush failed: ${error.message}`);\n } else {\n warn('TaskContext flush failed');\n }\n } finally {\n this.events = [];\n }\n }\n}\n"],"mappings":"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","names":["DEFAULT_TIMEOUT_MS","warn","warn"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/buffered-sender.ts","../src/client.ts","../src/digest.ts","../src/ids.ts","../src/registry.ts","../src/context.ts"],"sourcesContent":["export { init, shutdown, getClient, isEnabled, MarloClient } from './client';\nexport { task, TaskContext } from './context';\nexport { registerAgent, registerAgent as agent, getAgent } from './registry';\nexport { generateId } from './ids';\nexport { jsonDigest } from './digest';\nexport type {\n Scope,\n AgentDefinition,\n Event,\n LearningState,\n ToolDefinition,\n McpDefinition,\n ModelConfig,\n TokenUsage,\n LlmCallParams,\n} from './types';\n","import type { Event } from './types';\n\nconst DEFAULT_BATCH_SIZE = 50;\nconst DEFAULT_FLUSH_INTERVAL_MS = 1000;\nconst DEFAULT_RETRIES = 3;\nconst DEFAULT_RETRY_BACKOFF_MS = 500;\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport interface BufferedEventSenderConfig {\n eventsUrl: string;\n batchSize?: number;\n flushIntervalMs?: number;\n maxRetries?: number;\n retryBackoffMs?: number;\n}\n\nexport class BufferedEventSender {\n private readonly eventsUrl: string;\n private readonly batchSize: number;\n private readonly flushIntervalMs: number;\n private readonly maxRetries: number;\n private readonly retryBackoffMs: number;\n private queue: Event[] = [];\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private isShutdown = false;\n\n constructor(config: BufferedEventSenderConfig) {\n this.eventsUrl = config.eventsUrl;\n this.batchSize = Math.max(1, config.batchSize ?? DEFAULT_BATCH_SIZE);\n this.flushIntervalMs = Math.max(\n 100,\n config.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS\n );\n this.maxRetries = Math.max(1, config.maxRetries ?? DEFAULT_RETRIES);\n this.retryBackoffMs = Math.max(\n 100,\n config.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS\n );\n\n this.flushTimer = setInterval(() => {\n this.flushAsync().catch(() => {});\n }, this.flushIntervalMs);\n }\n\n enqueue(events: Event[]): void {\n if (!events.length || this.isShutdown) {\n return;\n }\n this.queue.push(...events);\n if (this.queue.length >= this.batchSize) {\n this.flushAsync().catch(() => {});\n }\n }\n\n async flush(): Promise<void> {\n await this.flushAsync();\n }\n\n async shutdown(): Promise<void> {\n this.isShutdown = true;\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushAsync();\n }\n\n private async flushAsync(): Promise<void> {\n while (this.queue.length > 0) {\n const batch = this.queue.splice(0, this.batchSize);\n const success = await this.sendWithRetry(batch);\n if (!success) {\n this.queue.unshift(...batch);\n return;\n }\n }\n }\n\n private async sendWithRetry(batch: Event[]): Promise<boolean> {\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n if (await this.sendBatch(batch)) {\n return true;\n }\n await sleep(this.retryBackoffMs * 2 ** attempt);\n }\n return false;\n }\n\n private async sendBatch(batch: Event[]): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(this.eventsUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(batch),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status >= 200 && response.status < 300) {\n return true;\n }\n warn(`Event send returned ${response.status}`);\n return false;\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n warn('Event send timed out');\n } else {\n warn(`Event send failed: ${error.message}`);\n }\n } else {\n warn('Event send failed');\n }\n return false;\n }\n }\n}\n","import { BufferedEventSender } from './buffered-sender';\nimport type { Event, LearningState, Scope } from './types';\n\nconst DEFAULT_ENDPOINT = 'http://localhost:8000';\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nconst LOCAL_SCOPE: Scope = {\n project_id: 'local',\n org_id: 'local',\n user_id: 'local',\n};\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction info(message: string): void {\n console.info(`[marlo] ${message}`);\n}\n\nlet _client: MarloClient | null = null;\nlet _enabled = false;\n\nexport class MarloClient {\n private readonly endpoint: string;\n private readonly _scope: Scope;\n private readonly sender: BufferedEventSender;\n\n constructor(endpoint: string, scope: Scope) {\n this.endpoint = endpoint.replace(/\\/+$/, '');\n this._scope = scope;\n this.sender = new BufferedEventSender({\n eventsUrl: `${this.endpoint}/events`,\n });\n }\n\n get scope(): Scope {\n return this._scope;\n }\n\n sendEvents(events: Event[]): void {\n this.sender.enqueue(events);\n }\n\n async flush(): Promise<void> {\n await this.sender.flush();\n }\n\n async shutdown(): Promise<void> {\n await this.sender.shutdown();\n }\n\n async fetchLearnings(learningKey: string): Promise<LearningState | null> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(`${this.endpoint}/learnings`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ learning_key: learningKey }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status < 200 || response.status >= 300) {\n return null;\n }\n\n const data = await response.json();\n return data.learning_state ?? null;\n } catch (error) {\n if (error instanceof Error) {\n warn(`Fetch learnings failed: ${error.message}`);\n } else {\n warn('Fetch learnings failed');\n }\n return null;\n }\n }\n}\n\nexport async function init(\n endpoint: string = DEFAULT_ENDPOINT\n): Promise<void> {\n try {\n const normalizedEndpoint = endpoint.replace(/\\/+$/, '');\n _client = new MarloClient(normalizedEndpoint, LOCAL_SCOPE);\n _enabled = true;\n info(`Marlo SDK initialized (local mode)`);\n } catch (error) {\n if (error instanceof Error) {\n warn(`Marlo init failed: ${error.message}`);\n } else {\n warn('Marlo init failed');\n }\n _enabled = false;\n }\n}\n\nexport function getClient(): MarloClient | null {\n return _client;\n}\n\nexport function isEnabled(): boolean {\n return _enabled;\n}\n\nexport async function shutdown(): Promise<void> {\n if (_client) {\n await _client.shutdown();\n _client = null;\n }\n _enabled = false;\n}\n","import { createHash } from 'crypto';\n\nfunction sortObject(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map(sortObject);\n }\n if (typeof value === 'object') {\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(value as Record<string, unknown>).sort();\n for (const key of keys) {\n sorted[key] = sortObject((value as Record<string, unknown>)[key]);\n }\n return sorted;\n }\n return value;\n}\n\nexport function jsonDigest(payload: unknown): string {\n const sorted = sortObject(payload);\n const encoded = JSON.stringify(sorted) ?? 'undefined';\n return createHash('sha256').update(encoded, 'utf-8').digest('hex');\n}\n","const ID_EPOCH_MS = 1700000000000;\nconst WORKER_ID_BITS = 10;\nconst SEQUENCE_BITS = 12;\nconst MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1;\nconst MAX_SEQUENCE = (1 << SEQUENCE_BITS) - 1;\nconst WORKER_ID_SHIFT = SEQUENCE_BITS;\nconst TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;\nconst SAFE_INT_MASK = BigInt(Number.MAX_SAFE_INTEGER);\n\nfunction parseWorkerId(): number {\n const raw = (process.env.MARLO_WORKER_ID ?? '0').trim();\n if (!raw) {\n return 0;\n }\n const workerId = parseInt(raw, 10);\n if (isNaN(workerId) || workerId < 0 || workerId > MAX_WORKER_ID) {\n return 0;\n }\n return workerId;\n}\n\nconst WORKER_ID = parseWorkerId();\n\nclass IdGenerator {\n private lastTs = 0;\n private sequence = 0;\n\n nextId(): number {\n let ts = Date.now();\n\n if (ts < this.lastTs) {\n ts = this.waitUntil(this.lastTs);\n }\n\n if (ts === this.lastTs) {\n this.sequence = (this.sequence + 1) & MAX_SEQUENCE;\n if (this.sequence === 0) {\n ts = this.waitUntil(this.lastTs + 1);\n }\n } else {\n this.sequence = 0;\n }\n\n this.lastTs = ts;\n const raw =\n (BigInt(ts - ID_EPOCH_MS) << BigInt(TIMESTAMP_SHIFT)) |\n (BigInt(WORKER_ID) << BigInt(WORKER_ID_SHIFT)) |\n BigInt(this.sequence);\n return Number(raw & SAFE_INT_MASK);\n }\n\n private waitUntil(targetMs: number): number {\n let ts = Date.now();\n while (ts < targetMs) {\n ts = Date.now();\n }\n return ts;\n }\n}\n\nconst idGenerator = new IdGenerator();\n\nexport function generateId(): number {\n return idGenerator.nextId();\n}\n","import { jsonDigest } from './digest';\nimport type {\n AgentDefinition,\n ToolDefinition,\n McpDefinition,\n ModelConfig,\n} from './types';\n\nclass AgentRegistry {\n private agents: Map<string, AgentDefinition> = new Map();\n\n register(definition: AgentDefinition): void {\n const existing = this.agents.get(definition.name);\n if (!existing) {\n this.agents.set(definition.name, definition);\n } else if (existing.definition_hash !== definition.definition_hash) {\n definition.sent = false;\n this.agents.set(definition.name, definition);\n } else {\n definition.sent = existing.sent;\n this.agents.set(definition.name, definition);\n }\n }\n\n get(name: string): AgentDefinition | null {\n return this.agents.get(name) ?? null;\n }\n\n markSent(name: string): void {\n const agent = this.agents.get(name);\n if (agent) {\n agent.sent = true;\n }\n }\n\n needsResend(name: string): boolean {\n const agent = this.agents.get(name);\n return agent !== null && agent !== undefined && !agent.sent;\n }\n}\n\nlet registry: AgentRegistry | null = null;\n\nfunction getRegistry(): AgentRegistry {\n if (!registry) {\n registry = new AgentRegistry();\n }\n return registry;\n}\n\nexport function registerAgent(\n name: string,\n systemPrompt: string,\n tools: ToolDefinition[],\n mcp?: McpDefinition[] | null,\n modelConfig?: ModelConfig | null\n): string {\n const definitionHash = jsonDigest({\n name,\n system_prompt: systemPrompt,\n tool_definitions: tools,\n mcp_definitions: mcp ?? null,\n model_config: modelConfig ?? null,\n });\n\n const definition: AgentDefinition = {\n name,\n system_prompt: systemPrompt,\n tools,\n mcp: mcp ?? null,\n model_config: modelConfig ?? null,\n definition_hash: definitionHash,\n sent: false,\n };\n\n getRegistry().register(definition);\n return definitionHash;\n}\n\nexport function getAgent(name: string): AgentDefinition | null {\n return getRegistry().get(name);\n}\n\nexport function markAgentSent(name: string): void {\n getRegistry().markSent(name);\n}\n\nexport function needsResend(name: string): boolean {\n return getRegistry().needsResend(name);\n}\n","import { getClient, isEnabled } from './client';\nimport { jsonDigest } from './digest';\nimport { generateId } from './ids';\nimport { getAgent, markAgentSent, needsResend } from './registry';\nimport type { Event, LearningState, LlmCallParams } from './types';\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction generateInvocationId(): string {\n return crypto.randomUUID();\n}\n\nfunction computeSessionId(projectId: string, threadId: string): number {\n const digest = jsonDigest(`${projectId}:${threadId}`);\n return parseInt(digest.slice(0, 16), 16);\n}\n\nexport function task(\n threadId: string,\n agent: string,\n threadName?: string\n): TaskContext {\n return new TaskContext(threadId, agent, threadName);\n}\n\nexport class TaskContext {\n private readonly threadId: string;\n private readonly agentName: string;\n private readonly threadName: string | undefined;\n private readonly parent: TaskContext | undefined;\n private taskId: number | null = null;\n private sessionId: number | null = null;\n private invocationId: string | null = null;\n private inputText: string | null = null;\n private outputText: string | null = null;\n private errorMessage: string | null = null;\n private events: Event[] = [];\n\n constructor(\n threadId: string,\n agent: string,\n threadName?: string,\n parent?: TaskContext\n ) {\n this.threadId = threadId;\n this.agentName = agent;\n this.threadName = threadName;\n this.parent = parent;\n }\n\n start(): this {\n try {\n const client = getClient();\n const projectId = client?.scope.project_id ?? '';\n this.sessionId = computeSessionId(projectId, this.threadId);\n this.taskId = generateId();\n this.invocationId = generateInvocationId();\n\n if (needsResend(this.agentName)) {\n const agentDef = getAgent(this.agentName);\n if (agentDef) {\n this.emit('agent_definition', {\n name: agentDef.name,\n system_prompt: agentDef.system_prompt,\n tool_definitions: agentDef.tools,\n mcp_definitions: agentDef.mcp,\n model_config: agentDef.model_config,\n definition_hash: agentDef.definition_hash,\n });\n markAgentSent(this.agentName);\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext start failed: ${error.message}`);\n } else {\n warn('TaskContext start failed');\n }\n }\n return this;\n }\n\n end(hasError?: boolean): void {\n try {\n const status =\n hasError || this.errorMessage !== null ? 'error' : 'success';\n const payload: Record<string, unknown> = { status };\n if (this.outputText !== null) {\n payload.final_answer = this.outputText;\n }\n if (this.errorMessage !== null) {\n payload.error = this.errorMessage;\n }\n this.emit('task_end', payload);\n this.flush();\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext end failed: ${error.message}`);\n } else {\n warn('TaskContext end failed');\n }\n }\n }\n\n input(text: string): void {\n try {\n this.inputText = text;\n const metadata: Record<string, unknown> = { thread_id: this.threadId };\n if (this.threadName !== undefined) {\n metadata.thread_name = this.threadName;\n }\n this.emit('task_start', { task: text, metadata });\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext input failed: ${error.message}`);\n } else {\n warn('TaskContext input failed');\n }\n }\n }\n\n output(text: string): void {\n try {\n this.outputText = text;\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext output failed: ${error.message}`);\n } else {\n warn('TaskContext output failed');\n }\n }\n }\n\n tool(\n name: string,\n input: Record<string, unknown>,\n output: unknown,\n error?: string\n ): void {\n try {\n const payload: Record<string, unknown> = {\n tool_name: name,\n input,\n output,\n };\n if (error !== undefined) {\n payload.error = error;\n }\n this.emit('tool_call', payload);\n } catch (err) {\n if (err instanceof Error) {\n warn(`TaskContext tool failed: ${err.message}`);\n } else {\n warn('TaskContext tool failed');\n }\n }\n }\n\n reasoning(text: string): void {\n try {\n this.emit('log', { reasoning: text });\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext reasoning failed: ${error.message}`);\n } else {\n warn('TaskContext reasoning failed');\n }\n }\n }\n\n llm(params: LlmCallParams): void {\n try {\n if (params.messages === undefined) {\n warn('llm() called without messages');\n }\n if (params.response === undefined) {\n warn('llm() called without response');\n }\n\n const payload: Record<string, unknown> = {\n model: params.model,\n usage: params.usage,\n };\n if (params.messages !== undefined) {\n payload.messages = params.messages;\n }\n if (params.response !== undefined) {\n payload.response = params.response;\n }\n this.emit('llm_call', payload);\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext llm failed: ${error.message}`);\n } else {\n warn('TaskContext llm failed');\n }\n }\n }\n\n error(message: string): void {\n try {\n this.errorMessage = message;\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext error failed: ${error.message}`);\n } else {\n warn('TaskContext error failed');\n }\n }\n }\n\n child(agent: string): TaskContext {\n return new TaskContext(this.threadId, agent, this.threadName, this);\n }\n\n async getLearnings(): Promise<LearningState | null> {\n try {\n const client = getClient();\n if (!client) {\n return null;\n }\n return await client.fetchLearnings(this.agentName);\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext getLearnings failed: ${error.message}`);\n } else {\n warn('TaskContext getLearnings failed');\n }\n return null;\n }\n }\n\n private emit(eventType: string, payload: Record<string, unknown>): void {\n const agentDef = getAgent(this.agentName);\n const agentId = agentDef?.name ?? this.agentName;\n const parentAgentId = this.parent?.agentName ?? null;\n\n const event: Event = {\n run_id: this.sessionId,\n agent_id: agentId,\n parent_agent_id: parentAgentId,\n invocation_id: this.invocationId,\n task_id: this.taskId,\n event_type: eventType,\n payload,\n };\n this.events.push(event);\n }\n\n private flush(): void {\n const client = getClient();\n if (!client || !isEnabled()) {\n this.events = [];\n return;\n }\n try {\n client.sendEvents(this.events);\n client.flush();\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext flush failed: ${error.message}`);\n } else {\n warn('TaskContext flush failed');\n }\n } finally {\n this.events = [];\n }\n }\n}\n"],"mappings":"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","names":["DEFAULT_TIMEOUT_MS","warn","warn"]}
|
package/dist/index.mjs
CHANGED
|
@@ -16,7 +16,6 @@ var BufferedEventSender = class {
|
|
|
16
16
|
this.flushTimer = null;
|
|
17
17
|
this.isShutdown = false;
|
|
18
18
|
this.eventsUrl = config.eventsUrl;
|
|
19
|
-
this.headers = { Authorization: `Bearer ${config.apiKey}` };
|
|
20
19
|
this.batchSize = Math.max(1, config.batchSize ?? DEFAULT_BATCH_SIZE);
|
|
21
20
|
this.flushIntervalMs = Math.max(
|
|
22
21
|
100,
|
|
@@ -79,7 +78,6 @@ var BufferedEventSender = class {
|
|
|
79
78
|
const response = await fetch(this.eventsUrl, {
|
|
80
79
|
method: "POST",
|
|
81
80
|
headers: {
|
|
82
|
-
...this.headers,
|
|
83
81
|
"Content-Type": "application/json"
|
|
84
82
|
},
|
|
85
83
|
body: JSON.stringify(batch),
|
|
@@ -107,8 +105,13 @@ var BufferedEventSender = class {
|
|
|
107
105
|
};
|
|
108
106
|
|
|
109
107
|
// src/client.ts
|
|
110
|
-
var DEFAULT_ENDPOINT = "
|
|
108
|
+
var DEFAULT_ENDPOINT = "http://localhost:8000";
|
|
111
109
|
var DEFAULT_TIMEOUT_MS2 = 5e3;
|
|
110
|
+
var LOCAL_SCOPE = {
|
|
111
|
+
project_id: "local",
|
|
112
|
+
org_id: "local",
|
|
113
|
+
user_id: "local"
|
|
114
|
+
};
|
|
112
115
|
function warn2(message) {
|
|
113
116
|
console.warn(`[marlo] ${message}`);
|
|
114
117
|
}
|
|
@@ -118,13 +121,11 @@ function info(message) {
|
|
|
118
121
|
var _client = null;
|
|
119
122
|
var _enabled = false;
|
|
120
123
|
var MarloClient = class {
|
|
121
|
-
constructor(
|
|
122
|
-
this.apiKey = apiKey;
|
|
124
|
+
constructor(endpoint, scope) {
|
|
123
125
|
this.endpoint = endpoint.replace(/\/+$/, "");
|
|
124
126
|
this._scope = scope;
|
|
125
127
|
this.sender = new BufferedEventSender({
|
|
126
|
-
eventsUrl: `${this.endpoint}/events
|
|
127
|
-
apiKey
|
|
128
|
+
eventsUrl: `${this.endpoint}/events`
|
|
128
129
|
});
|
|
129
130
|
}
|
|
130
131
|
get scope() {
|
|
@@ -146,7 +147,6 @@ var MarloClient = class {
|
|
|
146
147
|
const response = await fetch(`${this.endpoint}/learnings`, {
|
|
147
148
|
method: "POST",
|
|
148
149
|
headers: {
|
|
149
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
150
150
|
"Content-Type": "application/json"
|
|
151
151
|
},
|
|
152
152
|
body: JSON.stringify({ learning_key: learningKey }),
|
|
@@ -168,49 +168,15 @@ var MarloClient = class {
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
|
-
async function init(
|
|
172
|
-
const normalizedEndpoint = endpoint.replace(/\/+$/, "");
|
|
173
|
-
const scopeUrl = `${normalizedEndpoint}/scope`;
|
|
171
|
+
async function init(endpoint = DEFAULT_ENDPOINT) {
|
|
174
172
|
try {
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
const response = await fetch(scopeUrl, {
|
|
178
|
-
headers: { Authorization: `Bearer ${apiKey}` },
|
|
179
|
-
signal: controller.signal
|
|
180
|
-
});
|
|
181
|
-
clearTimeout(timeoutId);
|
|
182
|
-
if (response.status !== 200) {
|
|
183
|
-
warn2(`Marlo init failed: scope request returned ${response.status}`);
|
|
184
|
-
_enabled = false;
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
const payload = await response.json();
|
|
188
|
-
const scopeData = payload.scope ?? {};
|
|
189
|
-
const projectId = scopeData.project_id;
|
|
190
|
-
const orgId = scopeData.org_id;
|
|
191
|
-
const userId = scopeData.user_id;
|
|
192
|
-
if (typeof projectId !== "string" || !projectId.trim() || typeof orgId !== "string" || !orgId.trim() || typeof userId !== "string" || !userId.trim()) {
|
|
193
|
-
warn2("Marlo init failed: invalid scope response");
|
|
194
|
-
_enabled = false;
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
const scope = {
|
|
198
|
-
project_id: projectId.trim(),
|
|
199
|
-
org_id: orgId.trim(),
|
|
200
|
-
user_id: userId.trim()
|
|
201
|
-
};
|
|
202
|
-
_client = new MarloClient(apiKey, normalizedEndpoint, scope);
|
|
173
|
+
const normalizedEndpoint = endpoint.replace(/\/+$/, "");
|
|
174
|
+
_client = new MarloClient(normalizedEndpoint, LOCAL_SCOPE);
|
|
203
175
|
_enabled = true;
|
|
204
|
-
info(`Marlo SDK initialized
|
|
176
|
+
info(`Marlo SDK initialized (local mode)`);
|
|
205
177
|
} catch (error) {
|
|
206
178
|
if (error instanceof Error) {
|
|
207
|
-
|
|
208
|
-
warn2("Marlo init failed: timeout");
|
|
209
|
-
} else if (error.message.includes("ECONNREFUSED") || error.message.includes("fetch failed")) {
|
|
210
|
-
warn2("Marlo init failed: connection error");
|
|
211
|
-
} else {
|
|
212
|
-
warn2(`Marlo init failed: ${error.message}`);
|
|
213
|
-
}
|
|
179
|
+
warn2(`Marlo init failed: ${error.message}`);
|
|
214
180
|
} else {
|
|
215
181
|
warn2("Marlo init failed");
|
|
216
182
|
}
|
|
@@ -252,7 +218,7 @@ function sortObject(value) {
|
|
|
252
218
|
}
|
|
253
219
|
function jsonDigest(payload) {
|
|
254
220
|
const sorted = sortObject(payload);
|
|
255
|
-
const encoded = JSON.stringify(sorted);
|
|
221
|
+
const encoded = JSON.stringify(sorted) ?? "undefined";
|
|
256
222
|
return createHash("sha256").update(encoded, "utf-8").digest("hex");
|
|
257
223
|
}
|
|
258
224
|
|
|
@@ -264,6 +230,7 @@ var MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1;
|
|
|
264
230
|
var MAX_SEQUENCE = (1 << SEQUENCE_BITS) - 1;
|
|
265
231
|
var WORKER_ID_SHIFT = SEQUENCE_BITS;
|
|
266
232
|
var TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
|
|
233
|
+
var SAFE_INT_MASK = BigInt(Number.MAX_SAFE_INTEGER);
|
|
267
234
|
function parseWorkerId() {
|
|
268
235
|
const raw = (process.env.MARLO_WORKER_ID ?? "0").trim();
|
|
269
236
|
if (!raw) {
|
|
@@ -295,7 +262,8 @@ var IdGenerator = class {
|
|
|
295
262
|
this.sequence = 0;
|
|
296
263
|
}
|
|
297
264
|
this.lastTs = ts;
|
|
298
|
-
|
|
265
|
+
const raw = BigInt(ts - ID_EPOCH_MS) << BigInt(TIMESTAMP_SHIFT) | BigInt(WORKER_ID) << BigInt(WORKER_ID_SHIFT) | BigInt(this.sequence);
|
|
266
|
+
return Number(raw & SAFE_INT_MASK);
|
|
299
267
|
}
|
|
300
268
|
waitUntil(targetMs) {
|
|
301
269
|
let ts = Date.now();
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/buffered-sender.ts","../src/client.ts","../src/digest.ts","../src/ids.ts","../src/registry.ts","../src/context.ts"],"sourcesContent":["import type { Event } from './types';\n\nconst DEFAULT_BATCH_SIZE = 50;\nconst DEFAULT_FLUSH_INTERVAL_MS = 1000;\nconst DEFAULT_RETRIES = 3;\nconst DEFAULT_RETRY_BACKOFF_MS = 500;\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport interface BufferedEventSenderConfig {\n eventsUrl: string;\n apiKey: string;\n batchSize?: number;\n flushIntervalMs?: number;\n maxRetries?: number;\n retryBackoffMs?: number;\n}\n\nexport class BufferedEventSender {\n private readonly eventsUrl: string;\n private readonly headers: Record<string, string>;\n private readonly batchSize: number;\n private readonly flushIntervalMs: number;\n private readonly maxRetries: number;\n private readonly retryBackoffMs: number;\n private queue: Event[] = [];\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private isShutdown = false;\n\n constructor(config: BufferedEventSenderConfig) {\n this.eventsUrl = config.eventsUrl;\n this.headers = { Authorization: `Bearer ${config.apiKey}` };\n this.batchSize = Math.max(1, config.batchSize ?? DEFAULT_BATCH_SIZE);\n this.flushIntervalMs = Math.max(\n 100,\n config.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS\n );\n this.maxRetries = Math.max(1, config.maxRetries ?? DEFAULT_RETRIES);\n this.retryBackoffMs = Math.max(\n 100,\n config.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS\n );\n\n this.flushTimer = setInterval(() => {\n this.flushAsync().catch(() => {});\n }, this.flushIntervalMs);\n }\n\n enqueue(events: Event[]): void {\n if (!events.length || this.isShutdown) {\n return;\n }\n this.queue.push(...events);\n if (this.queue.length >= this.batchSize) {\n this.flushAsync().catch(() => {});\n }\n }\n\n async flush(): Promise<void> {\n await this.flushAsync();\n }\n\n async shutdown(): Promise<void> {\n this.isShutdown = true;\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushAsync();\n }\n\n private async flushAsync(): Promise<void> {\n while (this.queue.length > 0) {\n const batch = this.queue.splice(0, this.batchSize);\n const success = await this.sendWithRetry(batch);\n if (!success) {\n this.queue.unshift(...batch);\n return;\n }\n }\n }\n\n private async sendWithRetry(batch: Event[]): Promise<boolean> {\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n if (await this.sendBatch(batch)) {\n return true;\n }\n await sleep(this.retryBackoffMs * 2 ** attempt);\n }\n return false;\n }\n\n private async sendBatch(batch: Event[]): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(this.eventsUrl, {\n method: 'POST',\n headers: {\n ...this.headers,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(batch),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status >= 200 && response.status < 300) {\n return true;\n }\n warn(`Event send returned ${response.status}`);\n return false;\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n warn('Event send timed out');\n } else {\n warn(`Event send failed: ${error.message}`);\n }\n } else {\n warn('Event send failed');\n }\n return false;\n }\n }\n}\n","import { BufferedEventSender } from './buffered-sender';\nimport type { Event, LearningState, Scope } from './types';\n\nconst DEFAULT_ENDPOINT = 'https://marlo.marshmallo.ai';\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction info(message: string): void {\n console.info(`[marlo] ${message}`);\n}\n\nlet _client: MarloClient | null = null;\nlet _enabled = false;\n\nexport class MarloClient {\n private readonly apiKey: string;\n private readonly endpoint: string;\n private readonly _scope: Scope;\n private readonly sender: BufferedEventSender;\n\n constructor(apiKey: string, endpoint: string, scope: Scope) {\n this.apiKey = apiKey;\n this.endpoint = endpoint.replace(/\\/+$/, '');\n this._scope = scope;\n this.sender = new BufferedEventSender({\n eventsUrl: `${this.endpoint}/events`,\n apiKey,\n });\n }\n\n get scope(): Scope {\n return this._scope;\n }\n\n sendEvents(events: Event[]): void {\n this.sender.enqueue(events);\n }\n\n async flush(): Promise<void> {\n await this.sender.flush();\n }\n\n async shutdown(): Promise<void> {\n await this.sender.shutdown();\n }\n\n async fetchLearnings(learningKey: string): Promise<LearningState | null> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(`${this.endpoint}/learnings`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ learning_key: learningKey }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status < 200 || response.status >= 300) {\n return null;\n }\n\n const data = await response.json();\n return data.learning_state ?? null;\n } catch (error) {\n if (error instanceof Error) {\n warn(`Fetch learnings failed: ${error.message}`);\n } else {\n warn('Fetch learnings failed');\n }\n return null;\n }\n }\n}\n\nexport async function init(\n apiKey: string,\n endpoint: string = DEFAULT_ENDPOINT\n): Promise<void> {\n const normalizedEndpoint = endpoint.replace(/\\/+$/, '');\n const scopeUrl = `${normalizedEndpoint}/scope`;\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(scopeUrl, {\n headers: { Authorization: `Bearer ${apiKey}` },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status !== 200) {\n warn(`Marlo init failed: scope request returned ${response.status}`);\n _enabled = false;\n return;\n }\n\n const payload = await response.json();\n const scopeData = payload.scope ?? {};\n const projectId = scopeData.project_id;\n const orgId = scopeData.org_id;\n const userId = scopeData.user_id;\n\n if (\n typeof projectId !== 'string' ||\n !projectId.trim() ||\n typeof orgId !== 'string' ||\n !orgId.trim() ||\n typeof userId !== 'string' ||\n !userId.trim()\n ) {\n warn('Marlo init failed: invalid scope response');\n _enabled = false;\n return;\n }\n\n const scope: Scope = {\n project_id: projectId.trim(),\n org_id: orgId.trim(),\n user_id: userId.trim(),\n };\n\n _client = new MarloClient(apiKey, normalizedEndpoint, scope);\n _enabled = true;\n info(`Marlo SDK initialized for project ${projectId}`);\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n warn('Marlo init failed: timeout');\n } else if (\n error.message.includes('ECONNREFUSED') ||\n error.message.includes('fetch failed')\n ) {\n warn('Marlo init failed: connection error');\n } else {\n warn(`Marlo init failed: ${error.message}`);\n }\n } else {\n warn('Marlo init failed');\n }\n _enabled = false;\n }\n}\n\nexport function getClient(): MarloClient | null {\n return _client;\n}\n\nexport function isEnabled(): boolean {\n return _enabled;\n}\n\nexport async function shutdown(): Promise<void> {\n if (_client) {\n await _client.shutdown();\n _client = null;\n }\n _enabled = false;\n}\n","import { createHash } from 'crypto';\n\nfunction sortObject(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map(sortObject);\n }\n if (typeof value === 'object') {\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(value as Record<string, unknown>).sort();\n for (const key of keys) {\n sorted[key] = sortObject((value as Record<string, unknown>)[key]);\n }\n return sorted;\n }\n return value;\n}\n\nexport function jsonDigest(payload: unknown): string {\n const sorted = sortObject(payload);\n const encoded = JSON.stringify(sorted);\n return createHash('sha256').update(encoded, 'utf-8').digest('hex');\n}\n","const ID_EPOCH_MS = 1700000000000;\nconst WORKER_ID_BITS = 10;\nconst SEQUENCE_BITS = 12;\nconst MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1;\nconst MAX_SEQUENCE = (1 << SEQUENCE_BITS) - 1;\nconst WORKER_ID_SHIFT = SEQUENCE_BITS;\nconst TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;\n\nfunction parseWorkerId(): number {\n const raw = (process.env.MARLO_WORKER_ID ?? '0').trim();\n if (!raw) {\n return 0;\n }\n const workerId = parseInt(raw, 10);\n if (isNaN(workerId) || workerId < 0 || workerId > MAX_WORKER_ID) {\n return 0;\n }\n return workerId;\n}\n\nconst WORKER_ID = parseWorkerId();\n\nclass IdGenerator {\n private lastTs = 0;\n private sequence = 0;\n\n nextId(): number {\n let ts = Date.now();\n\n if (ts < this.lastTs) {\n ts = this.waitUntil(this.lastTs);\n }\n\n if (ts === this.lastTs) {\n this.sequence = (this.sequence + 1) & MAX_SEQUENCE;\n if (this.sequence === 0) {\n ts = this.waitUntil(this.lastTs + 1);\n }\n } else {\n this.sequence = 0;\n }\n\n this.lastTs = ts;\n return (\n ((ts - ID_EPOCH_MS) << TIMESTAMP_SHIFT) |\n (WORKER_ID << WORKER_ID_SHIFT) |\n this.sequence\n );\n }\n\n private waitUntil(targetMs: number): number {\n let ts = Date.now();\n while (ts < targetMs) {\n ts = Date.now();\n }\n return ts;\n }\n}\n\nconst idGenerator = new IdGenerator();\n\nexport function generateId(): number {\n return idGenerator.nextId();\n}\n","import { jsonDigest } from './digest';\nimport type {\n AgentDefinition,\n ToolDefinition,\n McpDefinition,\n ModelConfig,\n} from './types';\n\nclass AgentRegistry {\n private agents: Map<string, AgentDefinition> = new Map();\n\n register(definition: AgentDefinition): void {\n const existing = this.agents.get(definition.name);\n if (!existing) {\n this.agents.set(definition.name, definition);\n } else if (existing.definition_hash !== definition.definition_hash) {\n definition.sent = false;\n this.agents.set(definition.name, definition);\n } else {\n definition.sent = existing.sent;\n this.agents.set(definition.name, definition);\n }\n }\n\n get(name: string): AgentDefinition | null {\n return this.agents.get(name) ?? null;\n }\n\n markSent(name: string): void {\n const agent = this.agents.get(name);\n if (agent) {\n agent.sent = true;\n }\n }\n\n needsResend(name: string): boolean {\n const agent = this.agents.get(name);\n return agent !== null && agent !== undefined && !agent.sent;\n }\n}\n\nlet registry: AgentRegistry | null = null;\n\nfunction getRegistry(): AgentRegistry {\n if (!registry) {\n registry = new AgentRegistry();\n }\n return registry;\n}\n\nexport function registerAgent(\n name: string,\n systemPrompt: string,\n tools: ToolDefinition[],\n mcp?: McpDefinition[] | null,\n modelConfig?: ModelConfig | null\n): string {\n const definitionHash = jsonDigest({\n name,\n system_prompt: systemPrompt,\n tool_definitions: tools,\n mcp_definitions: mcp ?? null,\n model_config: modelConfig ?? null,\n });\n\n const definition: AgentDefinition = {\n name,\n system_prompt: systemPrompt,\n tools,\n mcp: mcp ?? null,\n model_config: modelConfig ?? null,\n definition_hash: definitionHash,\n sent: false,\n };\n\n getRegistry().register(definition);\n return definitionHash;\n}\n\nexport function getAgent(name: string): AgentDefinition | null {\n return getRegistry().get(name);\n}\n\nexport function markAgentSent(name: string): void {\n getRegistry().markSent(name);\n}\n\nexport function needsResend(name: string): boolean {\n return getRegistry().needsResend(name);\n}\n","import { getClient, isEnabled } from './client';\nimport { jsonDigest } from './digest';\nimport { generateId } from './ids';\nimport { getAgent, markAgentSent, needsResend } from './registry';\nimport type { Event, LearningState, LlmCallParams } from './types';\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction generateInvocationId(): string {\n return crypto.randomUUID();\n}\n\nfunction computeSessionId(projectId: string, threadId: string): number {\n const digest = jsonDigest(`${projectId}:${threadId}`);\n return parseInt(digest.slice(0, 16), 16);\n}\n\nexport function task(\n threadId: string,\n agent: string,\n threadName?: string\n): TaskContext {\n return new TaskContext(threadId, agent, threadName);\n}\n\nexport class TaskContext {\n private readonly threadId: string;\n private readonly agentName: string;\n private readonly threadName: string | undefined;\n private readonly parent: TaskContext | undefined;\n private taskId: number | null = null;\n private sessionId: number | null = null;\n private invocationId: string | null = null;\n private inputText: string | null = null;\n private outputText: string | null = null;\n private errorMessage: string | null = null;\n private events: Event[] = [];\n\n constructor(\n threadId: string,\n agent: string,\n threadName?: string,\n parent?: TaskContext\n ) {\n this.threadId = threadId;\n this.agentName = agent;\n this.threadName = threadName;\n this.parent = parent;\n }\n\n start(): this {\n try {\n const client = getClient();\n const projectId = client?.scope.project_id ?? '';\n this.sessionId = computeSessionId(projectId, this.threadId);\n this.taskId = generateId();\n this.invocationId = generateInvocationId();\n\n if (needsResend(this.agentName)) {\n const agentDef = getAgent(this.agentName);\n if (agentDef) {\n this.emit('agent_definition', {\n name: agentDef.name,\n system_prompt: agentDef.system_prompt,\n tool_definitions: agentDef.tools,\n mcp_definitions: agentDef.mcp,\n model_config: agentDef.model_config,\n definition_hash: agentDef.definition_hash,\n });\n markAgentSent(this.agentName);\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext start failed: ${error.message}`);\n } else {\n warn('TaskContext start failed');\n }\n }\n return this;\n }\n\n end(hasError?: boolean): void {\n try {\n const status =\n hasError || this.errorMessage !== null ? 'error' : 'success';\n const payload: Record<string, unknown> = { status };\n if (this.outputText !== null) {\n payload.final_answer = this.outputText;\n }\n if (this.errorMessage !== null) {\n payload.error = this.errorMessage;\n }\n this.emit('task_end', payload);\n this.flush();\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext end failed: ${error.message}`);\n } else {\n warn('TaskContext end failed');\n }\n }\n }\n\n input(text: string): void {\n try {\n this.inputText = text;\n const metadata: Record<string, unknown> = { thread_id: this.threadId };\n if (this.threadName !== undefined) {\n metadata.thread_name = this.threadName;\n }\n this.emit('task_start', { task: text, metadata });\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext input failed: ${error.message}`);\n } else {\n warn('TaskContext input failed');\n }\n }\n }\n\n output(text: string): void {\n try {\n this.outputText = text;\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext output failed: ${error.message}`);\n } else {\n warn('TaskContext output failed');\n }\n }\n }\n\n tool(\n name: string,\n input: Record<string, unknown>,\n output: unknown,\n error?: string\n ): void {\n try {\n const payload: Record<string, unknown> = {\n tool_name: name,\n input,\n output,\n };\n if (error !== undefined) {\n payload.error = error;\n }\n this.emit('tool_call', payload);\n } catch (err) {\n if (err instanceof Error) {\n warn(`TaskContext tool failed: ${err.message}`);\n } else {\n warn('TaskContext tool failed');\n }\n }\n }\n\n reasoning(text: string): void {\n try {\n this.emit('log', { reasoning: text });\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext reasoning failed: ${error.message}`);\n } else {\n warn('TaskContext reasoning failed');\n }\n }\n }\n\n llm(params: LlmCallParams): void {\n try {\n if (params.messages === undefined) {\n warn('llm() called without messages');\n }\n if (params.response === undefined) {\n warn('llm() called without response');\n }\n\n const payload: Record<string, unknown> = {\n model: params.model,\n usage: params.usage,\n };\n if (params.messages !== undefined) {\n payload.messages = params.messages;\n }\n if (params.response !== undefined) {\n payload.response = params.response;\n }\n this.emit('llm_call', payload);\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext llm failed: ${error.message}`);\n } else {\n warn('TaskContext llm failed');\n }\n }\n }\n\n error(message: string): void {\n try {\n this.errorMessage = message;\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext error failed: ${error.message}`);\n } else {\n warn('TaskContext error failed');\n }\n }\n }\n\n child(agent: string): TaskContext {\n return new TaskContext(this.threadId, agent, this.threadName, this);\n }\n\n async getLearnings(): Promise<LearningState | null> {\n try {\n const client = getClient();\n if (!client) {\n return null;\n }\n return await client.fetchLearnings(this.agentName);\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext getLearnings failed: ${error.message}`);\n } else {\n warn('TaskContext getLearnings failed');\n }\n return null;\n }\n }\n\n private emit(eventType: string, payload: Record<string, unknown>): void {\n const agentDef = getAgent(this.agentName);\n const agentId = agentDef?.name ?? this.agentName;\n const parentAgentId = this.parent?.agentName ?? null;\n\n const event: Event = {\n run_id: this.sessionId,\n agent_id: agentId,\n parent_agent_id: parentAgentId,\n invocation_id: this.invocationId,\n task_id: this.taskId,\n event_type: eventType,\n payload,\n };\n this.events.push(event);\n }\n\n private flush(): void {\n const client = getClient();\n if (!client || !isEnabled()) {\n this.events = [];\n return;\n }\n try {\n client.sendEvents(this.events);\n client.flush();\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext flush failed: ${error.message}`);\n } else {\n warn('TaskContext flush failed');\n }\n } finally {\n this.events = [];\n }\n }\n}\n"],"mappings":"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","names":["DEFAULT_TIMEOUT_MS","warn","warn"]}
|
|
1
|
+
{"version":3,"sources":["../src/buffered-sender.ts","../src/client.ts","../src/digest.ts","../src/ids.ts","../src/registry.ts","../src/context.ts"],"sourcesContent":["import type { Event } from './types';\n\nconst DEFAULT_BATCH_SIZE = 50;\nconst DEFAULT_FLUSH_INTERVAL_MS = 1000;\nconst DEFAULT_RETRIES = 3;\nconst DEFAULT_RETRY_BACKOFF_MS = 500;\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport interface BufferedEventSenderConfig {\n eventsUrl: string;\n batchSize?: number;\n flushIntervalMs?: number;\n maxRetries?: number;\n retryBackoffMs?: number;\n}\n\nexport class BufferedEventSender {\n private readonly eventsUrl: string;\n private readonly batchSize: number;\n private readonly flushIntervalMs: number;\n private readonly maxRetries: number;\n private readonly retryBackoffMs: number;\n private queue: Event[] = [];\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private isShutdown = false;\n\n constructor(config: BufferedEventSenderConfig) {\n this.eventsUrl = config.eventsUrl;\n this.batchSize = Math.max(1, config.batchSize ?? DEFAULT_BATCH_SIZE);\n this.flushIntervalMs = Math.max(\n 100,\n config.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS\n );\n this.maxRetries = Math.max(1, config.maxRetries ?? DEFAULT_RETRIES);\n this.retryBackoffMs = Math.max(\n 100,\n config.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS\n );\n\n this.flushTimer = setInterval(() => {\n this.flushAsync().catch(() => {});\n }, this.flushIntervalMs);\n }\n\n enqueue(events: Event[]): void {\n if (!events.length || this.isShutdown) {\n return;\n }\n this.queue.push(...events);\n if (this.queue.length >= this.batchSize) {\n this.flushAsync().catch(() => {});\n }\n }\n\n async flush(): Promise<void> {\n await this.flushAsync();\n }\n\n async shutdown(): Promise<void> {\n this.isShutdown = true;\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushAsync();\n }\n\n private async flushAsync(): Promise<void> {\n while (this.queue.length > 0) {\n const batch = this.queue.splice(0, this.batchSize);\n const success = await this.sendWithRetry(batch);\n if (!success) {\n this.queue.unshift(...batch);\n return;\n }\n }\n }\n\n private async sendWithRetry(batch: Event[]): Promise<boolean> {\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n if (await this.sendBatch(batch)) {\n return true;\n }\n await sleep(this.retryBackoffMs * 2 ** attempt);\n }\n return false;\n }\n\n private async sendBatch(batch: Event[]): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(this.eventsUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(batch),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status >= 200 && response.status < 300) {\n return true;\n }\n warn(`Event send returned ${response.status}`);\n return false;\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n warn('Event send timed out');\n } else {\n warn(`Event send failed: ${error.message}`);\n }\n } else {\n warn('Event send failed');\n }\n return false;\n }\n }\n}\n","import { BufferedEventSender } from './buffered-sender';\nimport type { Event, LearningState, Scope } from './types';\n\nconst DEFAULT_ENDPOINT = 'http://localhost:8000';\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nconst LOCAL_SCOPE: Scope = {\n project_id: 'local',\n org_id: 'local',\n user_id: 'local',\n};\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction info(message: string): void {\n console.info(`[marlo] ${message}`);\n}\n\nlet _client: MarloClient | null = null;\nlet _enabled = false;\n\nexport class MarloClient {\n private readonly endpoint: string;\n private readonly _scope: Scope;\n private readonly sender: BufferedEventSender;\n\n constructor(endpoint: string, scope: Scope) {\n this.endpoint = endpoint.replace(/\\/+$/, '');\n this._scope = scope;\n this.sender = new BufferedEventSender({\n eventsUrl: `${this.endpoint}/events`,\n });\n }\n\n get scope(): Scope {\n return this._scope;\n }\n\n sendEvents(events: Event[]): void {\n this.sender.enqueue(events);\n }\n\n async flush(): Promise<void> {\n await this.sender.flush();\n }\n\n async shutdown(): Promise<void> {\n await this.sender.shutdown();\n }\n\n async fetchLearnings(learningKey: string): Promise<LearningState | null> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(`${this.endpoint}/learnings`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ learning_key: learningKey }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status < 200 || response.status >= 300) {\n return null;\n }\n\n const data = await response.json();\n return data.learning_state ?? null;\n } catch (error) {\n if (error instanceof Error) {\n warn(`Fetch learnings failed: ${error.message}`);\n } else {\n warn('Fetch learnings failed');\n }\n return null;\n }\n }\n}\n\nexport async function init(\n endpoint: string = DEFAULT_ENDPOINT\n): Promise<void> {\n try {\n const normalizedEndpoint = endpoint.replace(/\\/+$/, '');\n _client = new MarloClient(normalizedEndpoint, LOCAL_SCOPE);\n _enabled = true;\n info(`Marlo SDK initialized (local mode)`);\n } catch (error) {\n if (error instanceof Error) {\n warn(`Marlo init failed: ${error.message}`);\n } else {\n warn('Marlo init failed');\n }\n _enabled = false;\n }\n}\n\nexport function getClient(): MarloClient | null {\n return _client;\n}\n\nexport function isEnabled(): boolean {\n return _enabled;\n}\n\nexport async function shutdown(): Promise<void> {\n if (_client) {\n await _client.shutdown();\n _client = null;\n }\n _enabled = false;\n}\n","import { createHash } from 'crypto';\n\nfunction sortObject(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map(sortObject);\n }\n if (typeof value === 'object') {\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(value as Record<string, unknown>).sort();\n for (const key of keys) {\n sorted[key] = sortObject((value as Record<string, unknown>)[key]);\n }\n return sorted;\n }\n return value;\n}\n\nexport function jsonDigest(payload: unknown): string {\n const sorted = sortObject(payload);\n const encoded = JSON.stringify(sorted) ?? 'undefined';\n return createHash('sha256').update(encoded, 'utf-8').digest('hex');\n}\n","const ID_EPOCH_MS = 1700000000000;\nconst WORKER_ID_BITS = 10;\nconst SEQUENCE_BITS = 12;\nconst MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1;\nconst MAX_SEQUENCE = (1 << SEQUENCE_BITS) - 1;\nconst WORKER_ID_SHIFT = SEQUENCE_BITS;\nconst TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;\nconst SAFE_INT_MASK = BigInt(Number.MAX_SAFE_INTEGER);\n\nfunction parseWorkerId(): number {\n const raw = (process.env.MARLO_WORKER_ID ?? '0').trim();\n if (!raw) {\n return 0;\n }\n const workerId = parseInt(raw, 10);\n if (isNaN(workerId) || workerId < 0 || workerId > MAX_WORKER_ID) {\n return 0;\n }\n return workerId;\n}\n\nconst WORKER_ID = parseWorkerId();\n\nclass IdGenerator {\n private lastTs = 0;\n private sequence = 0;\n\n nextId(): number {\n let ts = Date.now();\n\n if (ts < this.lastTs) {\n ts = this.waitUntil(this.lastTs);\n }\n\n if (ts === this.lastTs) {\n this.sequence = (this.sequence + 1) & MAX_SEQUENCE;\n if (this.sequence === 0) {\n ts = this.waitUntil(this.lastTs + 1);\n }\n } else {\n this.sequence = 0;\n }\n\n this.lastTs = ts;\n const raw =\n (BigInt(ts - ID_EPOCH_MS) << BigInt(TIMESTAMP_SHIFT)) |\n (BigInt(WORKER_ID) << BigInt(WORKER_ID_SHIFT)) |\n BigInt(this.sequence);\n return Number(raw & SAFE_INT_MASK);\n }\n\n private waitUntil(targetMs: number): number {\n let ts = Date.now();\n while (ts < targetMs) {\n ts = Date.now();\n }\n return ts;\n }\n}\n\nconst idGenerator = new IdGenerator();\n\nexport function generateId(): number {\n return idGenerator.nextId();\n}\n","import { jsonDigest } from './digest';\nimport type {\n AgentDefinition,\n ToolDefinition,\n McpDefinition,\n ModelConfig,\n} from './types';\n\nclass AgentRegistry {\n private agents: Map<string, AgentDefinition> = new Map();\n\n register(definition: AgentDefinition): void {\n const existing = this.agents.get(definition.name);\n if (!existing) {\n this.agents.set(definition.name, definition);\n } else if (existing.definition_hash !== definition.definition_hash) {\n definition.sent = false;\n this.agents.set(definition.name, definition);\n } else {\n definition.sent = existing.sent;\n this.agents.set(definition.name, definition);\n }\n }\n\n get(name: string): AgentDefinition | null {\n return this.agents.get(name) ?? null;\n }\n\n markSent(name: string): void {\n const agent = this.agents.get(name);\n if (agent) {\n agent.sent = true;\n }\n }\n\n needsResend(name: string): boolean {\n const agent = this.agents.get(name);\n return agent !== null && agent !== undefined && !agent.sent;\n }\n}\n\nlet registry: AgentRegistry | null = null;\n\nfunction getRegistry(): AgentRegistry {\n if (!registry) {\n registry = new AgentRegistry();\n }\n return registry;\n}\n\nexport function registerAgent(\n name: string,\n systemPrompt: string,\n tools: ToolDefinition[],\n mcp?: McpDefinition[] | null,\n modelConfig?: ModelConfig | null\n): string {\n const definitionHash = jsonDigest({\n name,\n system_prompt: systemPrompt,\n tool_definitions: tools,\n mcp_definitions: mcp ?? null,\n model_config: modelConfig ?? null,\n });\n\n const definition: AgentDefinition = {\n name,\n system_prompt: systemPrompt,\n tools,\n mcp: mcp ?? null,\n model_config: modelConfig ?? null,\n definition_hash: definitionHash,\n sent: false,\n };\n\n getRegistry().register(definition);\n return definitionHash;\n}\n\nexport function getAgent(name: string): AgentDefinition | null {\n return getRegistry().get(name);\n}\n\nexport function markAgentSent(name: string): void {\n getRegistry().markSent(name);\n}\n\nexport function needsResend(name: string): boolean {\n return getRegistry().needsResend(name);\n}\n","import { getClient, isEnabled } from './client';\nimport { jsonDigest } from './digest';\nimport { generateId } from './ids';\nimport { getAgent, markAgentSent, needsResend } from './registry';\nimport type { Event, LearningState, LlmCallParams } from './types';\n\nfunction warn(message: string): void {\n console.warn(`[marlo] ${message}`);\n}\n\nfunction generateInvocationId(): string {\n return crypto.randomUUID();\n}\n\nfunction computeSessionId(projectId: string, threadId: string): number {\n const digest = jsonDigest(`${projectId}:${threadId}`);\n return parseInt(digest.slice(0, 16), 16);\n}\n\nexport function task(\n threadId: string,\n agent: string,\n threadName?: string\n): TaskContext {\n return new TaskContext(threadId, agent, threadName);\n}\n\nexport class TaskContext {\n private readonly threadId: string;\n private readonly agentName: string;\n private readonly threadName: string | undefined;\n private readonly parent: TaskContext | undefined;\n private taskId: number | null = null;\n private sessionId: number | null = null;\n private invocationId: string | null = null;\n private inputText: string | null = null;\n private outputText: string | null = null;\n private errorMessage: string | null = null;\n private events: Event[] = [];\n\n constructor(\n threadId: string,\n agent: string,\n threadName?: string,\n parent?: TaskContext\n ) {\n this.threadId = threadId;\n this.agentName = agent;\n this.threadName = threadName;\n this.parent = parent;\n }\n\n start(): this {\n try {\n const client = getClient();\n const projectId = client?.scope.project_id ?? '';\n this.sessionId = computeSessionId(projectId, this.threadId);\n this.taskId = generateId();\n this.invocationId = generateInvocationId();\n\n if (needsResend(this.agentName)) {\n const agentDef = getAgent(this.agentName);\n if (agentDef) {\n this.emit('agent_definition', {\n name: agentDef.name,\n system_prompt: agentDef.system_prompt,\n tool_definitions: agentDef.tools,\n mcp_definitions: agentDef.mcp,\n model_config: agentDef.model_config,\n definition_hash: agentDef.definition_hash,\n });\n markAgentSent(this.agentName);\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext start failed: ${error.message}`);\n } else {\n warn('TaskContext start failed');\n }\n }\n return this;\n }\n\n end(hasError?: boolean): void {\n try {\n const status =\n hasError || this.errorMessage !== null ? 'error' : 'success';\n const payload: Record<string, unknown> = { status };\n if (this.outputText !== null) {\n payload.final_answer = this.outputText;\n }\n if (this.errorMessage !== null) {\n payload.error = this.errorMessage;\n }\n this.emit('task_end', payload);\n this.flush();\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext end failed: ${error.message}`);\n } else {\n warn('TaskContext end failed');\n }\n }\n }\n\n input(text: string): void {\n try {\n this.inputText = text;\n const metadata: Record<string, unknown> = { thread_id: this.threadId };\n if (this.threadName !== undefined) {\n metadata.thread_name = this.threadName;\n }\n this.emit('task_start', { task: text, metadata });\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext input failed: ${error.message}`);\n } else {\n warn('TaskContext input failed');\n }\n }\n }\n\n output(text: string): void {\n try {\n this.outputText = text;\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext output failed: ${error.message}`);\n } else {\n warn('TaskContext output failed');\n }\n }\n }\n\n tool(\n name: string,\n input: Record<string, unknown>,\n output: unknown,\n error?: string\n ): void {\n try {\n const payload: Record<string, unknown> = {\n tool_name: name,\n input,\n output,\n };\n if (error !== undefined) {\n payload.error = error;\n }\n this.emit('tool_call', payload);\n } catch (err) {\n if (err instanceof Error) {\n warn(`TaskContext tool failed: ${err.message}`);\n } else {\n warn('TaskContext tool failed');\n }\n }\n }\n\n reasoning(text: string): void {\n try {\n this.emit('log', { reasoning: text });\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext reasoning failed: ${error.message}`);\n } else {\n warn('TaskContext reasoning failed');\n }\n }\n }\n\n llm(params: LlmCallParams): void {\n try {\n if (params.messages === undefined) {\n warn('llm() called without messages');\n }\n if (params.response === undefined) {\n warn('llm() called without response');\n }\n\n const payload: Record<string, unknown> = {\n model: params.model,\n usage: params.usage,\n };\n if (params.messages !== undefined) {\n payload.messages = params.messages;\n }\n if (params.response !== undefined) {\n payload.response = params.response;\n }\n this.emit('llm_call', payload);\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext llm failed: ${error.message}`);\n } else {\n warn('TaskContext llm failed');\n }\n }\n }\n\n error(message: string): void {\n try {\n this.errorMessage = message;\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext error failed: ${error.message}`);\n } else {\n warn('TaskContext error failed');\n }\n }\n }\n\n child(agent: string): TaskContext {\n return new TaskContext(this.threadId, agent, this.threadName, this);\n }\n\n async getLearnings(): Promise<LearningState | null> {\n try {\n const client = getClient();\n if (!client) {\n return null;\n }\n return await client.fetchLearnings(this.agentName);\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext getLearnings failed: ${error.message}`);\n } else {\n warn('TaskContext getLearnings failed');\n }\n return null;\n }\n }\n\n private emit(eventType: string, payload: Record<string, unknown>): void {\n const agentDef = getAgent(this.agentName);\n const agentId = agentDef?.name ?? this.agentName;\n const parentAgentId = this.parent?.agentName ?? null;\n\n const event: Event = {\n run_id: this.sessionId,\n agent_id: agentId,\n parent_agent_id: parentAgentId,\n invocation_id: this.invocationId,\n task_id: this.taskId,\n event_type: eventType,\n payload,\n };\n this.events.push(event);\n }\n\n private flush(): void {\n const client = getClient();\n if (!client || !isEnabled()) {\n this.events = [];\n return;\n }\n try {\n client.sendEvents(this.events);\n client.flush();\n } catch (error) {\n if (error instanceof Error) {\n warn(`TaskContext flush failed: ${error.message}`);\n } else {\n warn('TaskContext flush failed');\n }\n } finally {\n this.events = [];\n }\n }\n}\n"],"mappings":"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","names":["DEFAULT_TIMEOUT_MS","warn","warn"]}
|