marco-agent 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Karan Kochar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # marco-agent
2
+
3
+ A simple, extensible AI agent built on [marco-harness](https://github.com/pyrotank41/MARCO). Works in CLI, server-side Node, and Next.js / Edge runtimes (anywhere `@anthropic-ai/sdk` runs).
4
+
5
+ `MarcoAgent` is a thin wrapper around the harness with sensible defaults — a system prompt, the Claude Sonnet 4.6 model, and one bundled tool (`current_time`). Use it as-is for quick scripts, or extend it with your own tools, hooks, and conversation history for project-specific agents.
6
+
7
+ > **Designing an integration?** See [`docs/architecture.md`](docs/architecture.md) for the library/app boundary, tool-category framework, and roadmap. [`docs/usage-tracking.md`](docs/usage-tracking.md) covers token + cost accounting in depth. [`docs/mcp-bridge.md`](docs/mcp-bridge.md) covers `fromMcpServer()` for wiring any MCP server into the agent.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install marco-agent
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```typescript
18
+ import { MarcoAgent } from 'marco-agent'
19
+
20
+ const agent = new MarcoAgent()
21
+ const { text } = await agent.ask('What time is it in Tokyo?')
22
+ console.log(text)
23
+ ```
24
+
25
+ Set `ANTHROPIC_API_KEY` in your environment before running.
26
+
27
+ ## CLI
28
+
29
+ ```bash
30
+ npx marco-agent "summarize the latest TC39 stage-4 proposals"
31
+ npx marco-agent --stream "write a haiku about TypeScript"
32
+ ```
33
+
34
+ ## Streaming
35
+
36
+ For chat UIs, server-sent events, etc. — get tokens as they arrive:
37
+
38
+ ```typescript
39
+ for await (const event of agent.stream('explain monads')) {
40
+ if (event.type === 'text') process.stdout.write(event.text)
41
+ else if (event.type === 'tool_call_start') console.log(`\n[calling ${event.name}]`)
42
+ else if (event.type === 'done') {
43
+ // event.result.messages is the canonical history — persist it for the next turn
44
+ }
45
+ }
46
+ ```
47
+
48
+ ## Multi-turn conversations
49
+
50
+ `ask()` and `stream()` both accept a `history` parameter — pass the previous turn's `result.messages` to continue:
51
+
52
+ ```typescript
53
+ let history: Message[] = []
54
+
55
+ const r1 = await agent.ask('My name is Karan.', history)
56
+ history = r1.messages
57
+
58
+ const r2 = await agent.ask('What did I just tell you?', history)
59
+ console.log(r2.text) // → "You told me your name is Karan."
60
+ ```
61
+
62
+ State lives with the caller, not the agent — so the same `MarcoAgent` instance is safe to share across concurrent web requests.
63
+
64
+ ## Web app integration (Next.js)
65
+
66
+ A complete streaming chat panel example lives in [`examples/nextjs/`](examples/nextjs/) — server route handler + client React component, plus notes on adapting it for project-specific tools.
67
+
68
+ ## Extending
69
+
70
+ Pass your own tools, hooks, system prompt, or model:
71
+
72
+ ```typescript
73
+ import { MarcoAgent } from 'marco-agent'
74
+ import { z } from 'zod'
75
+ import type { Tool } from 'marco-harness'
76
+
77
+ const calculatorTool: Tool = {
78
+ name: 'calculator',
79
+ description: 'Evaluate a basic arithmetic expression.',
80
+ inputJsonSchema: {
81
+ type: 'object',
82
+ properties: { expression: { type: 'string' } },
83
+ required: ['expression'],
84
+ },
85
+ validate: (i) => z.object({ expression: z.string() }).parse(i),
86
+ handler: async (input) => {
87
+ const { expression } = input as { expression: string }
88
+ return String(Function(`"use strict"; return (${expression})`)())
89
+ },
90
+ }
91
+
92
+ const agent = new MarcoAgent({
93
+ systemPrompt: 'You are a math tutor. Show your work.',
94
+ tools: [calculatorTool],
95
+ })
96
+ ```
97
+
98
+ ## License
99
+
100
+ MIT
@@ -0,0 +1,80 @@
1
+ import { type Tool, type Hooks, type ModelProvider, type Message } from 'marco-harness';
2
+ import { type CostUsage, type PricingFunction } from './usage.js';
3
+ import { type CompactionConfig } from './compaction.js';
4
+ export type BudgetConfig = {
5
+ maxInputTokensPerTurn?: number;
6
+ maxOutputTokensPerTurn?: number;
7
+ maxModelCallsPerTurn?: number;
8
+ maxCostUsdPerTurn?: number;
9
+ pricing?: PricingFunction;
10
+ onExceeded?: 'abort' | 'warn';
11
+ };
12
+ export type MarcoAgentOptions = {
13
+ systemPrompt?: string;
14
+ model?: string;
15
+ maxTokens?: number;
16
+ temperature?: number;
17
+ tools?: Tool[];
18
+ hooks?: Hooks;
19
+ provider?: ModelProvider;
20
+ apiKey?: string;
21
+ maxIterations?: number;
22
+ pricing?: PricingFunction;
23
+ budget?: BudgetConfig;
24
+ compaction?: CompactionConfig;
25
+ };
26
+ export type AskResult = {
27
+ text: string;
28
+ reasoning?: string;
29
+ messages: Message[];
30
+ usage: CostUsage;
31
+ compacted?: boolean;
32
+ };
33
+ export type StreamEvent = {
34
+ type: 'text';
35
+ text: string;
36
+ } | {
37
+ type: 'reasoning';
38
+ text: string;
39
+ } | {
40
+ type: 'tool_call_start';
41
+ id: string;
42
+ name: string;
43
+ } | {
44
+ type: 'tool_call_end';
45
+ id: string;
46
+ } | {
47
+ type: 'usage';
48
+ usage: CostUsage;
49
+ } | {
50
+ type: 'budget_exceeded';
51
+ reason: string;
52
+ usage: CostUsage;
53
+ } | {
54
+ type: 'compaction_start';
55
+ } | {
56
+ type: 'compaction_end';
57
+ messagesRemoved: number;
58
+ summaryTokens: number;
59
+ summaryText: string;
60
+ } | {
61
+ type: 'done';
62
+ result: AskResult;
63
+ };
64
+ export declare class BudgetExceededError extends Error {
65
+ readonly reason: string;
66
+ readonly usage: CostUsage;
67
+ constructor(reason: string, usage: CostUsage);
68
+ }
69
+ export declare class MarcoAgent {
70
+ private readonly options;
71
+ private readonly provider;
72
+ constructor(options?: MarcoAgentOptions);
73
+ ask(prompt: string, history?: Message[]): Promise<AskResult>;
74
+ stream(prompt: string, history?: Message[]): AsyncGenerator<StreamEvent, void, unknown>;
75
+ private model;
76
+ private checkBudget;
77
+ private assertWithinBudget;
78
+ private buildHarness;
79
+ }
80
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
package/dist/agent.js ADDED
@@ -0,0 +1,197 @@
1
+ import { Harness, AnthropicProvider } from 'marco-harness';
2
+ import { currentTimeTool } from './tools/current-time.js';
3
+ import { emptyUsage, addUsage, fromHarnessUsage, turnUsage, withCost } from './usage.js';
4
+ import { shouldCompact, performCompaction } from './compaction.js';
5
+ const DEFAULT_SYSTEM_PROMPT = `You are a helpful AI assistant built on the marco-harness framework.
6
+ Be concise, accurate, and use your tools when they would give a more reliable answer than guessing.`;
7
+ const DEFAULT_MODEL = 'claude-sonnet-4-6';
8
+ export class BudgetExceededError extends Error {
9
+ reason;
10
+ usage;
11
+ constructor(reason, usage) {
12
+ super(`Budget exceeded: ${reason}`);
13
+ this.reason = reason;
14
+ this.usage = usage;
15
+ this.name = 'BudgetExceededError';
16
+ }
17
+ }
18
+ export class MarcoAgent {
19
+ options;
20
+ provider;
21
+ constructor(options = {}) {
22
+ this.provider = options.provider ?? new AnthropicProvider({ apiKey: options.apiKey });
23
+ this.options = options;
24
+ }
25
+ async ask(prompt, history = []) {
26
+ let workingHistory = history;
27
+ let compacted = false;
28
+ let compactionUsage = emptyUsage();
29
+ if (shouldCompact(history, prompt, this.options.compaction)) {
30
+ const c = await performCompaction(this.provider, history, this.options.compaction);
31
+ workingHistory = c.history;
32
+ compacted = c.compacted;
33
+ compactionUsage = { ...emptyUsage(), inputTokens: c.usage.inputTokens, outputTokens: c.usage.outputTokens, modelCalls: 1 };
34
+ }
35
+ const harness = this.buildHarness(workingHistory, this.provider, () => undefined);
36
+ const result = await harness.run({ kind: 'user_message', text: prompt });
37
+ const turnTokens = turnUsage(result.messages, workingHistory.length);
38
+ const totalTokens = addUsage(compactionUsage, turnTokens);
39
+ const usage = withCost(totalTokens, this.model(), this.options.pricing);
40
+ this.assertWithinBudget(usage);
41
+ const out = buildAskResult(result.messages, workingHistory.length, usage);
42
+ return compacted ? { ...out, compacted: true } : out;
43
+ }
44
+ async *stream(prompt, history = []) {
45
+ let workingHistory = history;
46
+ let compacted = false;
47
+ let compactionUsage = emptyUsage();
48
+ if (shouldCompact(history, prompt, this.options.compaction)) {
49
+ yield { type: 'compaction_start' };
50
+ const c = await performCompaction(this.provider, history, this.options.compaction);
51
+ workingHistory = c.history;
52
+ compacted = c.compacted;
53
+ compactionUsage = { ...emptyUsage(), inputTokens: c.usage.inputTokens, outputTokens: c.usage.outputTokens, modelCalls: 1 };
54
+ yield { type: 'compaction_end', messagesRemoved: c.messagesRemoved, summaryTokens: c.usage.outputTokens, summaryText: c.summaryText };
55
+ }
56
+ const queue = [];
57
+ let resolveWait = null;
58
+ let done = false;
59
+ let runningUsage = compactionUsage;
60
+ let budgetTrip = null;
61
+ const wake = () => {
62
+ const r = resolveWait;
63
+ resolveWait = null;
64
+ r?.();
65
+ };
66
+ const innerProvider = this.provider;
67
+ const tee = {
68
+ async *stream(messages, tools, config) {
69
+ for await (const event of innerProvider.stream(messages, tools, config)) {
70
+ queue.push(event);
71
+ wake();
72
+ yield event;
73
+ }
74
+ },
75
+ };
76
+ const harness = this.buildHarness(workingHistory, tee, () => budgetTrip?.reason);
77
+ const runPromise = harness
78
+ .run({ kind: 'user_message', text: prompt })
79
+ .finally(() => { done = true; wake(); });
80
+ while (!done || queue.length > 0) {
81
+ while (queue.length > 0) {
82
+ const ev = queue.shift();
83
+ if (ev.type === 'text_delta')
84
+ yield { type: 'text', text: ev.text };
85
+ else if (ev.type === 'reasoning_delta')
86
+ yield { type: 'reasoning', text: ev.text };
87
+ else if (ev.type === 'tool_call_start')
88
+ yield { type: 'tool_call_start', id: ev.id, name: ev.name };
89
+ else if (ev.type === 'tool_call_end')
90
+ yield { type: 'tool_call_end', id: ev.id };
91
+ else if (ev.type === 'message_end') {
92
+ const callUsage = fromHarnessUsage(ev.message.usage);
93
+ runningUsage = addUsage(runningUsage, callUsage);
94
+ const costUsage = withCost(runningUsage, this.model(), this.options.pricing);
95
+ yield { type: 'usage', usage: costUsage };
96
+ const trip = this.checkBudget(costUsage);
97
+ if (trip) {
98
+ budgetTrip = { reason: trip, usage: costUsage };
99
+ yield { type: 'budget_exceeded', reason: trip, usage: costUsage };
100
+ }
101
+ }
102
+ }
103
+ if (!done)
104
+ await new Promise((resolve) => { resolveWait = resolve; });
105
+ }
106
+ const result = await runPromise;
107
+ const turnTokens = turnUsage(result.messages, workingHistory.length);
108
+ const totalTokens = addUsage(compactionUsage, turnTokens);
109
+ const finalUsage = withCost(totalTokens, this.model(), this.options.pricing);
110
+ const out = buildAskResult(result.messages, workingHistory.length, finalUsage);
111
+ yield { type: 'done', result: compacted ? { ...out, compacted: true } : out };
112
+ }
113
+ model() {
114
+ return this.options.model ?? DEFAULT_MODEL;
115
+ }
116
+ checkBudget(usage) {
117
+ const b = this.options.budget;
118
+ if (!b)
119
+ return null;
120
+ if (b.maxInputTokensPerTurn !== undefined && usage.inputTokens > b.maxInputTokensPerTurn)
121
+ return `inputTokens ${usage.inputTokens} > ${b.maxInputTokensPerTurn}`;
122
+ if (b.maxOutputTokensPerTurn !== undefined && usage.outputTokens > b.maxOutputTokensPerTurn)
123
+ return `outputTokens ${usage.outputTokens} > ${b.maxOutputTokensPerTurn}`;
124
+ if (b.maxModelCallsPerTurn !== undefined && usage.modelCalls > b.maxModelCallsPerTurn)
125
+ return `modelCalls ${usage.modelCalls} > ${b.maxModelCallsPerTurn}`;
126
+ if (b.maxCostUsdPerTurn !== undefined && usage.costUsd > b.maxCostUsdPerTurn)
127
+ return `costUsd ${usage.costUsd.toFixed(4)} > ${b.maxCostUsdPerTurn}`;
128
+ return null;
129
+ }
130
+ assertWithinBudget(usage) {
131
+ const trip = this.checkBudget(usage);
132
+ if (trip && this.options.budget?.onExceeded !== 'warn')
133
+ throw new BudgetExceededError(trip, usage);
134
+ }
135
+ buildHarness(initialMessages, provider, getBudgetTrip) {
136
+ const modelConfig = {
137
+ model: this.model(),
138
+ maxTokens: this.options.maxTokens ?? 4096,
139
+ systemPrompt: this.options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT,
140
+ ...(this.options.temperature !== undefined && { temperature: this.options.temperature }),
141
+ };
142
+ // Budget guard: runs before each model call. If the previous calls in this
143
+ // turn pushed us past the budget, reject the next call so the harness stops.
144
+ const userHooks = this.options.hooks ?? {};
145
+ const hooks = {
146
+ ...userHooks,
147
+ beforeModelCall: async (input) => {
148
+ const trip = getBudgetTrip();
149
+ if (trip && this.options.budget?.onExceeded !== 'warn') {
150
+ return { messages: input.messages, abort: true };
151
+ }
152
+ if (userHooks.beforeModelCall)
153
+ return await userHooks.beforeModelCall(input);
154
+ return { messages: input.messages };
155
+ },
156
+ };
157
+ return new Harness({
158
+ provider,
159
+ modelConfig,
160
+ tools: this.options.tools ?? [currentTimeTool],
161
+ hooks,
162
+ maxIterations: this.options.maxIterations,
163
+ initialMessages,
164
+ });
165
+ }
166
+ }
167
+ function extractFinalText(messages) {
168
+ for (let i = messages.length - 1; i >= 0; i--) {
169
+ const msg = messages[i];
170
+ if (msg.role === 'assistant' && msg.text) {
171
+ return msg.text;
172
+ }
173
+ }
174
+ return '';
175
+ }
176
+ // Concatenates reasoning across all assistant messages in the current turn
177
+ // (i.e. those after `historyLength`). Returns undefined if no reasoning was
178
+ // emitted, so the AskResult.reasoning field is absent rather than empty.
179
+ function extractTurnReasoning(messages, historyLength) {
180
+ const parts = [];
181
+ for (let i = historyLength; i < messages.length; i++) {
182
+ const msg = messages[i];
183
+ if (msg.role === 'assistant' && msg.reasoning)
184
+ parts.push(msg.reasoning);
185
+ }
186
+ return parts.length > 0 ? parts.join('\n\n') : undefined;
187
+ }
188
+ function buildAskResult(messages, historyLength, usage) {
189
+ const reasoning = extractTurnReasoning(messages, historyLength);
190
+ return {
191
+ text: extractFinalText(messages),
192
+ ...(reasoning !== undefined && { reasoning }),
193
+ messages,
194
+ usage,
195
+ };
196
+ }
197
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAqH,MAAM,eAAe,CAAA;AAC7K,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAoD,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC1I,OAAO,EAAyB,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAmDzF,MAAM,qBAAqB,GAAG;oGACsE,CAAA;AAEpG,MAAM,aAAa,GAAG,mBAAmB,CAAA;AAEzC,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAChB;IAAgC;IAA5D,YAA4B,MAAc,EAAkB,KAAgB;QAC1E,KAAK,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAA;QADT,WAAM,GAAN,MAAM,CAAQ;QAAkB,UAAK,GAAL,KAAK,CAAW;QAE1E,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,CAAC;CACF;AAED,MAAM,OAAO,UAAU;IACJ,OAAO,CAAmB;IAC1B,QAAQ,CAAe;IAExC,YAAY,UAA6B,EAAE;QACzC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;QACrF,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,MAAc,EAAE,UAAqB,EAAE;QAC/C,IAAI,cAAc,GAAG,OAAO,CAAA;QAC5B,IAAI,SAAS,GAAG,KAAK,CAAA;QACrB,IAAI,eAAe,GAAG,UAAU,EAAE,CAAA;QAElC,IAAI,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5D,MAAM,CAAC,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,UAAW,CAAC,CAAA;YACnF,cAAc,GAAG,CAAC,CAAC,OAAO,CAAA;YAC1B,SAAS,GAAG,CAAC,CAAC,SAAS,CAAA;YACvB,eAAe,GAAG,EAAE,GAAG,UAAU,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,EAAE,CAAC,EAAE,CAAA;QAC5H,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QACjF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QACxE,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;QACpE,MAAM,WAAW,GAAG,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;QACzD,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACvE,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;QAE9B,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QACzE,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;IACtD,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,MAAc,EAAE,UAAqB,EAAE;QACnD,IAAI,cAAc,GAAG,OAAO,CAAA;QAC5B,IAAI,SAAS,GAAG,KAAK,CAAA;QACrB,IAAI,eAAe,GAAG,UAAU,EAAE,CAAA;QAElC,IAAI,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5D,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAA;YAClC,MAAM,CAAC,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,UAAW,CAAC,CAAA;YACnF,cAAc,GAAG,CAAC,CAAC,OAAO,CAAA;YAC1B,SAAS,GAAG,CAAC,CAAC,SAAS,CAAA;YACvB,eAAe,GAAG,EAAE,GAAG,UAAU,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,EAAE,CAAC,EAAE,CAAA;YAC1H,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC,CAAC,eAAe,EAAE,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;QACvI,CAAC;QAED,MAAM,KAAK,GAAiB,EAAE,CAAA;QAC9B,IAAI,WAAW,GAAwB,IAAI,CAAA;QAC3C,IAAI,IAAI,GAAG,KAAK,CAAA;QAChB,IAAI,YAAY,GAAG,eAAe,CAAA;QAClC,IAAI,UAAU,GAAgD,IAAI,CAAA;QAElE,MAAM,IAAI,GAAG,GAAS,EAAE;YACtB,MAAM,CAAC,GAAG,WAAW,CAAA;YACrB,WAAW,GAAG,IAAI,CAAA;YAClB,CAAC,EAAE,EAAE,CAAA;QACP,CAAC,CAAA;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAA;QACnC,MAAM,GAAG,GAAkB;YACzB,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM;gBACnC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,aAAa,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;oBACxE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;oBACjB,IAAI,EAAE,CAAA;oBACN,MAAM,KAAK,CAAA;gBACb,CAAC;YACH,CAAC;SACF,CAAA;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;QAChF,MAAM,UAAU,GAAG,OAAO;aACvB,GAAG,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;aAC3C,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;QAEzC,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,EAAG,CAAA;gBACzB,IAAI,EAAE,CAAC,IAAI,KAAK,YAAY;oBAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;qBAC9D,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB;oBAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;qBAC7E,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB;oBAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;qBAC9F,IAAI,EAAE,CAAC,IAAI,KAAK,eAAe;oBAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAA;qBAC3E,IAAI,EAAE,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;oBACnC,MAAM,SAAS,GAAG,gBAAgB,CAAE,EAAE,CAAC,OAA4B,CAAC,KAAK,CAAC,CAAA;oBAC1E,YAAY,GAAG,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;oBAChD,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;oBAC5E,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;oBACzC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;oBACxC,IAAI,IAAI,EAAE,CAAC;wBACT,UAAU,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;wBAC/C,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;oBACnE,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,GAAG,WAAW,GAAG,OAAO,CAAA,CAAC,CAAC,CAAC,CAAA;QAC5E,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAA;QAC/B,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;QACpE,MAAM,WAAW,GAAG,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;QACzD,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC5E,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAC9E,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAA;IAC/E,CAAC;IAEO,KAAK;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,aAAa,CAAA;IAC5C,CAAC;IAEO,WAAW,CAAC,KAAgB;QAClC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA;QAC7B,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACnB,IAAI,CAAC,CAAC,qBAAqB,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,qBAAqB;YAAE,OAAO,eAAe,KAAK,CAAC,WAAW,MAAM,CAAC,CAAC,qBAAqB,EAAE,CAAA;QAChK,IAAI,CAAC,CAAC,sBAAsB,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,sBAAsB;YAAE,OAAO,gBAAgB,KAAK,CAAC,YAAY,MAAM,CAAC,CAAC,sBAAsB,EAAE,CAAA;QACtK,IAAI,CAAC,CAAC,oBAAoB,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,oBAAoB;YAAE,OAAO,cAAc,KAAK,CAAC,UAAU,MAAM,CAAC,CAAC,oBAAoB,EAAE,CAAA;QAC1J,IAAI,CAAC,CAAC,iBAAiB,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,iBAAiB;YAAE,OAAO,WAAW,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,iBAAiB,EAAE,CAAA;QACnJ,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,kBAAkB,CAAC,KAAgB;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QACpC,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,MAAM;YAAE,MAAM,IAAI,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IACpG,CAAC;IAEO,YAAY,CAAC,eAA0B,EAAE,QAAuB,EAAE,aAAuC;QAC/G,MAAM,WAAW,GAAgB;YAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;YACnB,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI;YACzC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,qBAAqB;YAChE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;SACzF,CAAA;QAED,2EAA2E;QAC3E,6EAA6E;QAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAA;QAC1C,MAAM,KAAK,GAAU;YACnB,GAAG,SAAS;YACZ,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBAC/B,MAAM,IAAI,GAAG,aAAa,EAAE,CAAA;gBAC5B,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,MAAM,EAAE,CAAC;oBACvD,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;gBAClD,CAAC;gBACD,IAAI,SAAS,CAAC,eAAe;oBAAE,OAAO,MAAM,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;gBAC5E,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAA;YACrC,CAAC;SACF,CAAA;QAED,OAAO,IAAI,OAAO,CAAC;YACjB,QAAQ;YACR,WAAW;YACX,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,eAAe,CAAC;YAC9C,KAAK;YACL,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;YACzC,eAAe;SAChB,CAAC,CAAA;IACJ,CAAC;CACF;AAED,SAAS,gBAAgB,CAAC,QAAmB;IAC3C,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QACvB,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YACzC,OAAO,GAAG,CAAC,IAAI,CAAA;QACjB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,2EAA2E;AAC3E,4EAA4E;AAC5E,yEAAyE;AACzE,SAAS,oBAAoB,CAAC,QAAmB,EAAE,aAAqB;IACtE,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrD,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QACvB,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC1E,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC1D,CAAC;AAED,SAAS,cAAc,CAAC,QAAmB,EAAE,aAAqB,EAAE,KAAgB;IAClF,MAAM,SAAS,GAAG,oBAAoB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAA;IAC/D,OAAO;QACL,IAAI,EAAE,gBAAgB,CAAC,QAAQ,CAAC;QAChC,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7C,QAAQ;QACR,KAAK;KACN,CAAA;AACH,CAAC"}
package/dist/bin.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
package/dist/bin.js ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ import { argv, env, exit, stdout, stderr } from 'node:process';
3
+ import { MarcoAgent } from './agent.js';
4
+ async function main() {
5
+ const args = argv.slice(2);
6
+ const streamMode = args[0] === '--stream' || args[0] === '-s';
7
+ const prompt = (streamMode ? args.slice(1) : args).join(' ').trim();
8
+ if (!prompt) {
9
+ stderr.write('Usage: marco-agent [--stream] "<your prompt>"\n');
10
+ exit(1);
11
+ }
12
+ if (!env.ANTHROPIC_API_KEY) {
13
+ stderr.write('Missing ANTHROPIC_API_KEY environment variable.\n');
14
+ exit(1);
15
+ }
16
+ const agent = new MarcoAgent();
17
+ if (streamMode) {
18
+ for await (const event of agent.stream(prompt)) {
19
+ if (event.type === 'text')
20
+ stdout.write(event.text);
21
+ else if (event.type === 'done')
22
+ stdout.write('\n');
23
+ }
24
+ }
25
+ else {
26
+ const result = await agent.ask(prompt);
27
+ stdout.write(result.text + '\n');
28
+ }
29
+ }
30
+ main().catch((err) => {
31
+ stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
32
+ exit(1);
33
+ });
34
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAC7D,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IAEnE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAA;QAC/D,IAAI,CAAC,CAAC,CAAC,CAAA;IACT,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAA;QACjE,IAAI,CAAC,CAAC,CAAC,CAAA;IACT,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAA;IAE9B,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;gBAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;iBAC9C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;gBAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACpD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IAClC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC5E,IAAI,CAAC,CAAC,CAAC,CAAA;AACT,CAAC,CAAC,CAAA"}
@@ -0,0 +1,20 @@
1
+ import type { Message, ModelProvider } from 'marco-harness';
2
+ export type CompactionConfig = {
3
+ summaryModel: string;
4
+ summaryPrompt: string;
5
+ triggerAtInputTokens?: number;
6
+ keepLastTurns?: number;
7
+ };
8
+ export type CompactionResult = {
9
+ history: Message[];
10
+ compacted: boolean;
11
+ usage: {
12
+ inputTokens: number;
13
+ outputTokens: number;
14
+ };
15
+ messagesRemoved: number;
16
+ summaryText: string;
17
+ };
18
+ export declare function shouldCompact(history: Message[], prompt: string, config: CompactionConfig | undefined): boolean;
19
+ export declare function performCompaction(provider: ModelProvider, history: Message[], config: CompactionConfig): Promise<CompactionResult>;
20
+ //# sourceMappingURL=compaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../src/compaction.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG;IAE7B,YAAY,EAAE,MAAM,CAAA;IAEpB,aAAa,EAAE,MAAM,CAAA;IAErB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAG7B,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAElB,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;IAEpD,eAAe,EAAE,MAAM,CAAA;IAIvB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAKD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAAE,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,gBAAgB,GAAG,SAAS,GACnC,OAAO,CAyBT;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,OAAO,EAAE,EAClB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA8D3B"}
@@ -0,0 +1,119 @@
1
+ // Compaction — summarize older conversation history when token use grows
2
+ // past a threshold, keeping the most recent N turns verbatim.
3
+ //
4
+ // Layer placement: this is an opinion (when to compact, what to keep, how to
5
+ // summarize) and lives in marco-agent, not marco-harness. The harness stays
6
+ // agnostic about conversation hygiene.
7
+ //
8
+ // Trigger: uses the LAST assistant message's actual usage.inputTokens
9
+ // (real measurement) plus a rough estimate of the new prompt's tokens.
10
+ // More honest than a tokenizer-based pre-count and dependency-free.
11
+ //
12
+ // Defaults policy: triggerAtInputTokens defaults to 150_000 because even with
13
+ // massive context windows, cost / latency / attention-degradation kick in
14
+ // well before the model's hard limit. summaryModel and summaryPrompt have NO
15
+ // default — the library can't know what model your API key supports, and a
16
+ // generic prompt would mismatch most agent domains.
17
+ const DEFAULT_TRIGGER = 150_000;
18
+ const DEFAULT_KEEP_LAST_TURNS = 4;
19
+ export function shouldCompact(history, prompt, config) {
20
+ if (!config)
21
+ return false;
22
+ const trigger = config.triggerAtInputTokens ?? DEFAULT_TRIGGER;
23
+ // Use the last assistant turn's actual input tokens as the truth signal.
24
+ // If we never made a model call yet, there's nothing to compact against.
25
+ let lastInputTokens = 0;
26
+ for (let i = history.length - 1; i >= 0; i--) {
27
+ const m = history[i];
28
+ if (m.role === 'assistant') {
29
+ lastInputTokens = m.usage?.inputTokens ?? 0;
30
+ break;
31
+ }
32
+ }
33
+ if (lastInputTokens === 0)
34
+ return false;
35
+ // Rough char-to-token approximation; deliberately conservative-leaning.
36
+ const estimatedNewPromptTokens = Math.ceil(prompt.length / 4);
37
+ if (lastInputTokens + estimatedNewPromptTokens <= trigger)
38
+ return false;
39
+ // Don't compact if we don't have more turns than we'd keep.
40
+ const keep = config.keepLastTurns ?? DEFAULT_KEEP_LAST_TURNS;
41
+ const userCount = history.filter((m) => m.role === 'user').length;
42
+ return userCount > keep;
43
+ }
44
+ export async function performCompaction(provider, history, config) {
45
+ const keep = config.keepLastTurns ?? DEFAULT_KEEP_LAST_TURNS;
46
+ // Boundary = index of the (keep-th from end) user message. Everything
47
+ // STRICTLY before that index becomes the prefix to summarize; the boundary
48
+ // index and everything after is kept verbatim.
49
+ let userSeen = 0;
50
+ let boundary = -1;
51
+ for (let i = history.length - 1; i >= 0; i--) {
52
+ if (history[i].role === 'user') {
53
+ userSeen++;
54
+ if (userSeen === keep) {
55
+ boundary = i;
56
+ break;
57
+ }
58
+ }
59
+ }
60
+ if (boundary <= 0) {
61
+ // Not enough user messages to compact (already validated by shouldCompact,
62
+ // but be defensive).
63
+ return { history, compacted: false, usage: { inputTokens: 0, outputTokens: 0 }, messagesRemoved: 0, summaryText: '' };
64
+ }
65
+ const prefix = history.slice(0, boundary);
66
+ const recent = history.slice(boundary);
67
+ const stringified = messagesToText(prefix);
68
+ const summaryUserMessage = {
69
+ role: 'user',
70
+ text: `${config.summaryPrompt}\n\n--- conversation to summarize ---\n${stringified}`,
71
+ };
72
+ let summaryText = '';
73
+ let inputTokens = 0;
74
+ let outputTokens = 0;
75
+ for await (const ev of provider.stream([summaryUserMessage], [], { model: config.summaryModel, maxTokens: 4000 })) {
76
+ if (ev.type === 'text_delta')
77
+ summaryText += ev.text;
78
+ else if (ev.type === 'message_end') {
79
+ summaryText = ev.message.text ?? summaryText;
80
+ inputTokens = ev.message.usage.inputTokens;
81
+ outputTokens = ev.message.usage.outputTokens;
82
+ }
83
+ }
84
+ const summaryMessage = {
85
+ role: 'system',
86
+ text: `Summary of earlier conversation:\n${summaryText.trim()}`,
87
+ };
88
+ const trimmedSummary = summaryText.trim();
89
+ return {
90
+ history: [summaryMessage, ...recent],
91
+ compacted: true,
92
+ usage: { inputTokens, outputTokens },
93
+ messagesRemoved: prefix.length,
94
+ summaryText: trimmedSummary,
95
+ };
96
+ }
97
+ function messagesToText(messages) {
98
+ return messages
99
+ .map((m) => {
100
+ if (m.role === 'system')
101
+ return `[system] ${m.text}`;
102
+ if (m.role === 'user')
103
+ return `[user] ${m.text}`;
104
+ if (m.role === 'assistant') {
105
+ const parts = [];
106
+ if (m.text)
107
+ parts.push(`[assistant] ${m.text}`);
108
+ for (const tc of m.toolCalls) {
109
+ parts.push(`[assistant tool_call ${tc.name}] ${JSON.stringify(tc.input)}`);
110
+ }
111
+ return parts.join('\n');
112
+ }
113
+ if (m.role === 'tool')
114
+ return `[tool result${m.isError ? ' ERROR' : ''}] ${m.content}`;
115
+ return '';
116
+ })
117
+ .join('\n\n');
118
+ }
119
+ //# sourceMappingURL=compaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.js","sourceRoot":"","sources":["../src/compaction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export { MarcoAgent, BudgetExceededError, type MarcoAgentOptions, type AskResult, type StreamEvent, type BudgetConfig } from './agent.js';
2
+ export { type CompactionConfig, type CompactionResult, shouldCompact, performCompaction } from './compaction.js';
3
+ export { currentTimeTool } from './tools/current-time.js';
4
+ export { toolFromZod, z, type ToolFromZodOptions } from './tool-from-zod.js';
5
+ export { defaultAnthropicPricing, emptyUsage, addUsage, withCost, type Usage, type CostUsage, type PricingFunction } from './usage.js';
6
+ export { fromMcpServer, type FromMcpServerOptions } from './mcp.js';
7
+ export { AnthropicProvider, OpenAICompatibleProvider, MockProvider } from 'marco-harness';
8
+ export type { Tool, Hooks, ModelProvider, ModelConfig, Message, AnthropicProviderOptions, OpenAICompatibleProviderOptions } from 'marco-harness';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AACzI,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAChH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAA;AACtI,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAA;AACnE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACzF,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { MarcoAgent, BudgetExceededError } from './agent.js';
2
+ export { shouldCompact, performCompaction } from './compaction.js';
3
+ export { currentTimeTool } from './tools/current-time.js';
4
+ export { toolFromZod, z } from './tool-from-zod.js';
5
+ export { defaultAnthropicPricing, emptyUsage, addUsage, withCost } from './usage.js';
6
+ export { fromMcpServer } from './mcp.js';
7
+ export { AnthropicProvider, OpenAICompatibleProvider, MockProvider } from 'marco-harness';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAA+E,MAAM,YAAY,CAAA;AACzI,OAAO,EAAgD,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAChH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,WAAW,EAAE,CAAC,EAA2B,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAoD,MAAM,YAAY,CAAA;AACtI,OAAO,EAAE,aAAa,EAA6B,MAAM,UAAU,CAAA;AACnE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { Tool } from 'marco-harness';
2
+ export type FromMcpServerOptions = {
3
+ url: string;
4
+ headers?: Record<string, string>;
5
+ contextArgs?: Record<string, unknown>;
6
+ include?: string[];
7
+ exclude?: string[];
8
+ fetch?: typeof globalThis.fetch;
9
+ };
10
+ export declare function fromMcpServer(opts: FromMcpServerOptions): Promise<Tool[]>;
11
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEzC,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAElB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAChC,CAAA;AAoDD,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CA2B/E"}
package/dist/mcp.js ADDED
@@ -0,0 +1,65 @@
1
+ // fromMcpServer — MCP-server-to-Tool bridge.
2
+ //
3
+ // Pure function. Takes resolved values (url, headers, contextArgs) and returns
4
+ // a Tool[] ready to plug into MarcoAgent. No env reads, no file reads, no
5
+ // secret resolution — those concerns live in marco-agent-cli's config layer
6
+ // or in the embedding app's own auth flow.
7
+ //
8
+ // Transport: HTTP + JSON-RPC 2.0. (stdio transport can come later.)
9
+ //
10
+ // Multi-tenant pattern: contextArgs are spread INTO every tool call's
11
+ // arguments AFTER the model's args, so the model cannot override them. This
12
+ // is the security boundary that lets a SaaS pass `target_user_id` per
13
+ // request without trusting the model.
14
+ let nextId = 1;
15
+ async function jsonRpc(url, method, params, headers, fetchImpl) {
16
+ const res = await fetchImpl(url, {
17
+ method: 'POST',
18
+ headers: { 'content-type': 'application/json', ...(headers ?? {}) },
19
+ body: JSON.stringify({ jsonrpc: '2.0', id: nextId++, method, params }),
20
+ });
21
+ if (!res.ok)
22
+ throw new Error(`MCP HTTP ${res.status}: ${await res.text()}`);
23
+ const json = (await res.json());
24
+ if (json.error)
25
+ throw new Error(`MCP RPC error: ${json.error.message}`);
26
+ if (json.result === undefined)
27
+ throw new Error('MCP RPC: empty result');
28
+ return json.result;
29
+ }
30
+ function resultToText(r) {
31
+ if (r.isError) {
32
+ const msg = r.content?.find((c) => c.type === 'text')?.text ?? 'MCP tool returned error';
33
+ throw new Error(msg);
34
+ }
35
+ if (r.structuredContent !== undefined)
36
+ return JSON.stringify(r.structuredContent);
37
+ if (r.content)
38
+ return r.content.map((c) => c.text ?? '').join('\n').trim();
39
+ return '';
40
+ }
41
+ export async function fromMcpServer(opts) {
42
+ const fetchImpl = opts.fetch ?? globalThis.fetch;
43
+ if (!fetchImpl)
44
+ throw new Error('fromMcpServer: no fetch implementation available');
45
+ const list = await jsonRpc(opts.url, 'tools/list', {}, opts.headers, fetchImpl);
46
+ let tools = list.tools ?? [];
47
+ if (opts.include)
48
+ tools = tools.filter((t) => opts.include.includes(t.name));
49
+ if (opts.exclude)
50
+ tools = tools.filter((t) => !opts.exclude.includes(t.name));
51
+ return tools.map((t) => ({
52
+ name: t.name,
53
+ description: t.description ?? '',
54
+ inputJsonSchema: t.inputSchema ?? { type: 'object', properties: {} },
55
+ // The MCP server is the source of truth for input validation. Pass through.
56
+ validate: (input) => input,
57
+ handler: async (input) => {
58
+ const modelArgs = (typeof input === 'object' && input !== null) ? input : {};
59
+ const args = { ...modelArgs, ...(opts.contextArgs ?? {}) };
60
+ const result = await jsonRpc(opts.url, 'tools/call', { name: t.name, arguments: args }, opts.headers, fetchImpl);
61
+ return resultToText(result);
62
+ },
63
+ }));
64
+ }
65
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { z, type ZodType } from 'zod/v4';
2
+ import type { Tool, ToolContext } from 'marco-harness';
3
+ export type ToolFromZodOptions<S extends ZodType> = {
4
+ name: string;
5
+ description: string;
6
+ schema: S;
7
+ handler: (input: z.infer<S>, ctx: ToolContext) => Promise<string>;
8
+ category?: string;
9
+ permissionLevel?: 'auto' | 'confirm' | 'always-ask';
10
+ };
11
+ export declare function toolFromZod<S extends ZodType>(opts: ToolFromZodOptions<S>): Tool;
12
+ export { z };
13
+ //# sourceMappingURL=tool-from-zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-from-zod.d.ts","sourceRoot":"","sources":["../src/tool-from-zod.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,CAAC,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEtD,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,OAAO,IAAI;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,CAAC,CAAA;IACT,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAAA;CACpD,CAAA;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,OAAO,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,CAWhF;AAKD,OAAO,EAAE,CAAC,EAAE,CAAA"}
@@ -0,0 +1,27 @@
1
+ // toolFromZod — define a Tool from a single zod schema.
2
+ //
3
+ // Without this helper, every Tool requires writing the JSON Schema by hand
4
+ // AND a separate `validate` function — two sources of truth that can drift.
5
+ // With this helper, both are derived from the same zod schema.
6
+ //
7
+ // Uses zod's v4 API (`zod/v4`, available since zod 3.24) for native JSON
8
+ // Schema export. No extra dep; zod is already a peer for any consumer that
9
+ // wants this helper.
10
+ import { z } from 'zod/v4';
11
+ export function toolFromZod(opts) {
12
+ const jsonSchema = z.toJSONSchema(opts.schema);
13
+ return {
14
+ name: opts.name,
15
+ description: opts.description,
16
+ inputJsonSchema: jsonSchema,
17
+ validate: (input) => opts.schema.parse(input),
18
+ handler: opts.handler,
19
+ ...(opts.category !== undefined && { category: opts.category }),
20
+ ...(opts.permissionLevel !== undefined && { permissionLevel: opts.permissionLevel }),
21
+ };
22
+ }
23
+ // Re-export zod's v4 z so consumers can do
24
+ // import { toolFromZod, z } from 'marco-agent'
25
+ // without managing the zod/v4 import path themselves.
26
+ export { z };
27
+ //# sourceMappingURL=tool-from-zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-from-zod.js","sourceRoot":"","sources":["../src/tool-from-zod.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,+DAA+D;AAC/D,EAAE;AACF,yEAAyE;AACzE,2EAA2E;AAC3E,qBAAqB;AAErB,OAAO,EAAE,CAAC,EAAgB,MAAM,QAAQ,CAAA;AAYxC,MAAM,UAAU,WAAW,CAAoB,IAA2B;IACxE,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAA4B,CAAA;IACzE,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,eAAe,EAAE,UAAU;QAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;QAC7C,OAAO,EAAE,IAAI,CAAC,OAA0B;QACxC,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/D,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;KACrF,CAAA;AACH,CAAC;AAED,2CAA2C;AAC3C,iDAAiD;AACjD,sDAAsD;AACtD,OAAO,EAAE,CAAC,EAAE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const currentTimeTool: import("marco-harness").Tool;
2
+ //# sourceMappingURL=current-time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"current-time.d.ts","sourceRoot":"","sources":["../../src/tools/current-time.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,8BAQ1B,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { toolFromZod, z } from '../tool-from-zod.js';
2
+ export const currentTimeTool = toolFromZod({
3
+ name: 'current_time',
4
+ description: 'Returns the current date and time. Optionally accepts an IANA timezone (e.g. "America/Chicago", "UTC"). Defaults to UTC.',
5
+ schema: z.object({
6
+ timezone: z.string().optional().describe('IANA timezone identifier. Defaults to UTC.'),
7
+ }),
8
+ handler: async ({ timezone = 'UTC' }) => new Date().toLocaleString('en-US', { timeZone: timezone, dateStyle: 'full', timeStyle: 'long' }),
9
+ });
10
+ //# sourceMappingURL=current-time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"current-time.js","sourceRoot":"","sources":["../../src/tools/current-time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAA;AAEpD,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;IACzC,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,0HAA0H;IACvI,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;KACvF,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,GAAG,KAAK,EAAE,EAAE,EAAE,CACtC,IAAI,IAAI,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;CACnG,CAAC,CAAA"}
@@ -0,0 +1,19 @@
1
+ import type { Message, Usage as HarnessUsage } from 'marco-harness';
2
+ export type Usage = {
3
+ inputTokens: number;
4
+ outputTokens: number;
5
+ cacheReadTokens: number;
6
+ cacheCreationTokens: number;
7
+ modelCalls: number;
8
+ };
9
+ export type CostUsage = Usage & {
10
+ costUsd: number;
11
+ };
12
+ export type PricingFunction = (model: string, usage: Usage) => number;
13
+ export declare const emptyUsage: () => Usage;
14
+ export declare function addUsage(a: Usage, b: Usage): Usage;
15
+ export declare function fromHarnessUsage(u: HarnessUsage | undefined): Usage;
16
+ export declare function turnUsage(messages: Message[], historyLength: number): Usage;
17
+ export declare const defaultAnthropicPricing: PricingFunction;
18
+ export declare function withCost(usage: Usage, model: string, pricing?: PricingFunction): CostUsage;
19
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,YAAY,EAAE,MAAM,eAAe,CAAA;AAEnE,MAAM,MAAM,KAAK,GAAG;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;IACvB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG;IAC9B,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,CAAA;AAErE,eAAO,MAAM,UAAU,QAAO,KAM5B,CAAA;AAEF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAQlD;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,KAAK,CASnE;AAKD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,KAAK,CAS3E;AAaD,eAAO,MAAM,uBAAuB,EAAE,eASrC,CAAA;AAQD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAG1F"}
package/dist/usage.js ADDED
@@ -0,0 +1,69 @@
1
+ export const emptyUsage = () => ({
2
+ inputTokens: 0,
3
+ outputTokens: 0,
4
+ cacheReadTokens: 0,
5
+ cacheCreationTokens: 0,
6
+ modelCalls: 0,
7
+ });
8
+ export function addUsage(a, b) {
9
+ return {
10
+ inputTokens: a.inputTokens + b.inputTokens,
11
+ outputTokens: a.outputTokens + b.outputTokens,
12
+ cacheReadTokens: a.cacheReadTokens + b.cacheReadTokens,
13
+ cacheCreationTokens: a.cacheCreationTokens + b.cacheCreationTokens,
14
+ modelCalls: a.modelCalls + b.modelCalls,
15
+ };
16
+ }
17
+ export function fromHarnessUsage(u) {
18
+ if (!u)
19
+ return emptyUsage();
20
+ return {
21
+ inputTokens: u.inputTokens,
22
+ outputTokens: u.outputTokens,
23
+ cacheReadTokens: 0,
24
+ cacheCreationTokens: 0,
25
+ modelCalls: 1,
26
+ };
27
+ }
28
+ // Sums usage across all assistant messages in `messages` after `historyLength`.
29
+ // Used to compute the usage attributable to the current turn, ignoring any
30
+ // usage that was already carried in from prior conversation history.
31
+ export function turnUsage(messages, historyLength) {
32
+ let total = emptyUsage();
33
+ for (let i = historyLength; i < messages.length; i++) {
34
+ const m = messages[i];
35
+ if (m.role === 'assistant') {
36
+ total = addUsage(total, fromHarnessUsage(m.usage));
37
+ }
38
+ }
39
+ return total;
40
+ }
41
+ // Default pricing for current Anthropic models. Snapshot as of 2026-04-28 — pass
42
+ // your own PricingFunction for accuracy or to model negotiated rates.
43
+ //
44
+ // Rates are in dollars per 1M tokens. Cache rates only apply when the upstream
45
+ // SDK starts emitting cache breakdowns; until then those token counts are zero.
46
+ const ANTHROPIC_RATES_USD_PER_MTOK = {
47
+ 'claude-opus-4-7': { input: 15.00, output: 75.00, cacheRead: 1.50, cacheCreate: 18.75 },
48
+ 'claude-sonnet-4-6': { input: 3.00, output: 15.00, cacheRead: 0.30, cacheCreate: 3.75 },
49
+ 'claude-haiku-4-5': { input: 0.80, output: 4.00, cacheRead: 0.08, cacheCreate: 1.00 },
50
+ };
51
+ export const defaultAnthropicPricing = (model, usage) => {
52
+ const rates = ANTHROPIC_RATES_USD_PER_MTOK[stripModelSuffix(model)];
53
+ if (!rates)
54
+ return 0;
55
+ return (usage.inputTokens * rates.input +
56
+ usage.outputTokens * rates.output +
57
+ usage.cacheReadTokens * rates.cacheRead +
58
+ usage.cacheCreationTokens * rates.cacheCreate) / 1_000_000;
59
+ };
60
+ function stripModelSuffix(model) {
61
+ // Match either base name (claude-sonnet-4-6) or dated variant
62
+ // (claude-sonnet-4-6-20251001) by trimming a trailing -YYYYMMDD.
63
+ return model.replace(/-\d{8}$/, '');
64
+ }
65
+ export function withCost(usage, model, pricing) {
66
+ const fn = pricing ?? defaultAnthropicPricing;
67
+ return { ...usage, costUsd: fn(model, usage) };
68
+ }
69
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "marco-agent",
3
+ "version": "0.1.0",
4
+ "description": "A simple, extensible AI agent built on marco-harness.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "bin": {
15
+ "marco-agent": "./dist/bin.js"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest",
26
+ "typecheck": "tsc --noEmit",
27
+ "start": "tsx src/bin.ts"
28
+ },
29
+ "dependencies": {
30
+ "marco-harness": "^0.2.1",
31
+ "zod": "^3.25.76"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^22.10.0",
35
+ "tsx": "^4.19.0",
36
+ "typescript": "^5.7.0",
37
+ "vitest": "^2.1.0"
38
+ },
39
+ "engines": {
40
+ "node": ">=22"
41
+ },
42
+ "keywords": [
43
+ "ai",
44
+ "ai-agent",
45
+ "agent",
46
+ "anthropic",
47
+ "claude",
48
+ "marco",
49
+ "marco-harness"
50
+ ],
51
+ "author": "Karan Kochar <karankochar13@gmail.com> (https://karankochar.dev)",
52
+ "license": "MIT"
53
+ }