@appliqation/agent-core 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 +21 -0
- package/README.md +40 -0
- package/dist/appq/index.d.ts +3 -0
- package/dist/appq/index.d.ts.map +1 -0
- package/dist/appq/index.js +3 -0
- package/dist/appq/index.js.map +1 -0
- package/dist/appq/mcpClient.d.ts +52 -0
- package/dist/appq/mcpClient.d.ts.map +1 -0
- package/dist/appq/mcpClient.js +79 -0
- package/dist/appq/mcpClient.js.map +1 -0
- package/dist/appq/scenarioResolvers.d.ts +60 -0
- package/dist/appq/scenarioResolvers.d.ts.map +1 -0
- package/dist/appq/scenarioResolvers.js +114 -0
- package/dist/appq/scenarioResolvers.js.map +1 -0
- package/dist/audit/index.d.ts +2 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +2 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/sink.d.ts +69 -0
- package/dist/audit/sink.d.ts.map +1 -0
- package/dist/audit/sink.js +93 -0
- package/dist/audit/sink.js.map +1 -0
- package/dist/config/helpers.d.ts +3 -0
- package/dist/config/helpers.d.ts.map +1 -0
- package/dist/config/helpers.js +16 -0
- package/dist/config/helpers.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/engine/budget.d.ts +18 -0
- package/dist/engine/budget.d.ts.map +1 -0
- package/dist/engine/budget.js +31 -0
- package/dist/engine/budget.js.map +1 -0
- package/dist/engine/index.d.ts +4 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +4 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/loop.d.ts +20 -0
- package/dist/engine/loop.d.ts.map +1 -0
- package/dist/engine/loop.js +60 -0
- package/dist/engine/loop.js.map +1 -0
- package/dist/engine/workflowRunner.d.ts +27 -0
- package/dist/engine/workflowRunner.d.ts.map +1 -0
- package/dist/engine/workflowRunner.js +31 -0
- package/dist/engine/workflowRunner.js.map +1 -0
- package/dist/evidence/capture.d.ts +53 -0
- package/dist/evidence/capture.d.ts.map +1 -0
- package/dist/evidence/capture.js +80 -0
- package/dist/evidence/capture.js.map +1 -0
- package/dist/evidence/index.d.ts +2 -0
- package/dist/evidence/index.d.ts.map +1 -0
- package/dist/evidence/index.js +2 -0
- package/dist/evidence/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/anthropic.d.ts +4 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +113 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/index.d.ts +3 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai.d.ts +4 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +87 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/tools/apiTools.d.ts +21 -0
- package/dist/tools/apiTools.d.ts.map +1 -0
- package/dist/tools/apiTools.js +82 -0
- package/dist/tools/apiTools.js.map +1 -0
- package/dist/tools/authState.d.ts +21 -0
- package/dist/tools/authState.d.ts.map +1 -0
- package/dist/tools/authState.js +29 -0
- package/dist/tools/authState.js.map +1 -0
- package/dist/tools/browserTools.d.ts +35 -0
- package/dist/tools/browserTools.d.ts.map +1 -0
- package/dist/tools/browserTools.js +313 -0
- package/dist/tools/browserTools.js.map +1 -0
- package/dist/tools/destructiveActionGate.d.ts +10 -0
- package/dist/tools/destructiveActionGate.d.ts.map +1 -0
- package/dist/tools/destructiveActionGate.js +40 -0
- package/dist/tools/destructiveActionGate.js.map +1 -0
- package/dist/tools/gatedDispatcher.d.ts +15 -0
- package/dist/tools/gatedDispatcher.d.ts.map +1 -0
- package/dist/tools/gatedDispatcher.js +39 -0
- package/dist/tools/gatedDispatcher.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +8 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/projectContext.d.ts +4 -0
- package/dist/tools/projectContext.d.ts.map +1 -0
- package/dist/tools/projectContext.js +37 -0
- package/dist/tools/projectContext.js.map +1 -0
- package/dist/tools/roleInference.d.ts +65 -0
- package/dist/tools/roleInference.d.ts.map +1 -0
- package/dist/tools/roleInference.js +128 -0
- package/dist/tools/roleInference.js.map +1 -0
- package/dist/types.d.ts +78 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { RunBudget } from '../types.js';
|
|
2
|
+
export declare class BudgetTracker {
|
|
3
|
+
private readonly budget;
|
|
4
|
+
private calls;
|
|
5
|
+
private pages;
|
|
6
|
+
private readonly startedAt;
|
|
7
|
+
constructor(budget: RunBudget);
|
|
8
|
+
countCall(): void;
|
|
9
|
+
countPage(): void;
|
|
10
|
+
/** Returns a human-readable reason if a cap has been exceeded, else null. */
|
|
11
|
+
exceeded(): string | null;
|
|
12
|
+
state(): {
|
|
13
|
+
calls: number;
|
|
14
|
+
pages: number;
|
|
15
|
+
elapsedMillis: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/engine/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,qBAAa,aAAa;IAKZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAEX,MAAM,EAAE,SAAS;IAE9C,SAAS,IAAI,IAAI;IAIjB,SAAS,IAAI,IAAI;IAIjB,6EAA6E;IAC7E,QAAQ,IAAI,MAAM,GAAG,IAAI;IAUzB,KAAK;;;;;CAGN"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export class BudgetTracker {
|
|
2
|
+
budget;
|
|
3
|
+
calls = 0;
|
|
4
|
+
pages = 0;
|
|
5
|
+
startedAt = Date.now();
|
|
6
|
+
constructor(budget) {
|
|
7
|
+
this.budget = budget;
|
|
8
|
+
}
|
|
9
|
+
countCall() {
|
|
10
|
+
this.calls += 1;
|
|
11
|
+
}
|
|
12
|
+
countPage() {
|
|
13
|
+
this.pages += 1;
|
|
14
|
+
}
|
|
15
|
+
/** Returns a human-readable reason if a cap has been exceeded, else null. */
|
|
16
|
+
exceeded() {
|
|
17
|
+
if (this.calls >= this.budget.maxCalls)
|
|
18
|
+
return `${this.calls} tool calls (cap ${this.budget.maxCalls})`;
|
|
19
|
+
if (this.pages >= this.budget.maxPages)
|
|
20
|
+
return `${this.pages} page navigations (cap ${this.budget.maxPages})`;
|
|
21
|
+
const elapsed = Date.now() - this.startedAt;
|
|
22
|
+
if (elapsed >= this.budget.maxMillis) {
|
|
23
|
+
return `${Math.round(elapsed / 1000)}s elapsed (cap ${Math.round(this.budget.maxMillis / 1000)}s)`;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
state() {
|
|
28
|
+
return { calls: this.calls, pages: this.pages, elapsedMillis: Date.now() - this.startedAt };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/engine/budget.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IAKK;IAJrB,KAAK,GAAG,CAAC,CAAC;IACV,KAAK,GAAG,CAAC,CAAC;IACD,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAExC,YAA6B,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;IAAG,CAAC;IAElD,SAAS;QACP,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,6EAA6E;IAC7E,QAAQ;QACN,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,oBAAoB,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC;QACxG,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,0BAA0B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC;QAC9G,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5C,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACrC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,kBAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;QACrG,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAC9F,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAmB,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAA2C,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { LlmToolDef, ProviderAdapter, RunBudget, ToolDispatcher } from '../types.js';
|
|
2
|
+
export interface LoopResult {
|
|
3
|
+
report: string;
|
|
4
|
+
turns: number;
|
|
5
|
+
budgetExceeded: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function runLoop(args: {
|
|
8
|
+
adapter: ProviderAdapter;
|
|
9
|
+
system: string;
|
|
10
|
+
seedMessage: string;
|
|
11
|
+
tools: LlmToolDef[];
|
|
12
|
+
dispatch: ToolDispatcher;
|
|
13
|
+
budget: RunBudget;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
onEvent?: (event: {
|
|
16
|
+
type: string;
|
|
17
|
+
detail?: unknown;
|
|
18
|
+
}) => void;
|
|
19
|
+
}): Promise<LoopResult>;
|
|
20
|
+
//# sourceMappingURL=loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGtG,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/D,GAAG,OAAO,CAAC,UAAU,CAAC,CAwDtB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// The generic think->act->observe loop. Workflow-agnostic: it knows nothing
|
|
2
|
+
// about any specific named workflow — it just executes whatever system
|
|
3
|
+
// prompt and tool palette it's given until the model stops calling tools,
|
|
4
|
+
// with a hard turn/call/time budget cap.
|
|
5
|
+
import { BudgetTracker } from './budget.js';
|
|
6
|
+
export async function runLoop(args) {
|
|
7
|
+
const { adapter, system, tools, dispatch, budget, signal, onEvent } = args;
|
|
8
|
+
const tracker = new BudgetTracker(budget);
|
|
9
|
+
const messages = [{ role: 'user', content: args.seedMessage }];
|
|
10
|
+
let budgetExceeded = false;
|
|
11
|
+
for (let turn = 0; turn < budget.maxTurns; turn++) {
|
|
12
|
+
if (signal?.aborted)
|
|
13
|
+
throw new Error('Run aborted');
|
|
14
|
+
const cap = tracker.exceeded();
|
|
15
|
+
if (cap) {
|
|
16
|
+
budgetExceeded = true;
|
|
17
|
+
messages.push({
|
|
18
|
+
role: 'user',
|
|
19
|
+
content: `Budget note: ${cap}. Stop probing and produce your final report now. Do not call any tool in this turn.`,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const response = await adapter.complete({ system, messages, tools, signal });
|
|
23
|
+
onEvent?.({ type: 'assistant', detail: response.text });
|
|
24
|
+
if (response.usage)
|
|
25
|
+
onEvent?.({ type: 'usage', detail: response.usage });
|
|
26
|
+
if (response.toolCalls.length === 0) {
|
|
27
|
+
return { report: response.text, turns: turn + 1, budgetExceeded };
|
|
28
|
+
}
|
|
29
|
+
messages.push({ role: 'assistant', content: response.text, toolCalls: response.toolCalls });
|
|
30
|
+
for (const call of response.toolCalls) {
|
|
31
|
+
if (signal?.aborted)
|
|
32
|
+
throw new Error('Run aborted');
|
|
33
|
+
tracker.countCall();
|
|
34
|
+
if (call.name === 'browser_navigate')
|
|
35
|
+
tracker.countPage();
|
|
36
|
+
let result;
|
|
37
|
+
try {
|
|
38
|
+
result = await dispatch(call.name, call.arguments);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
result = { ok: false, text: `Tool error: ${err.message}` };
|
|
42
|
+
}
|
|
43
|
+
onEvent?.({
|
|
44
|
+
type: 'tool',
|
|
45
|
+
detail: {
|
|
46
|
+
name: call.name,
|
|
47
|
+
args: call.arguments,
|
|
48
|
+
result: result.text,
|
|
49
|
+
images: result.images?.length ? result.images.length : undefined,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
messages.push({ role: 'tool', toolCallId: call.id, content: result.text, images: result.images });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
onEvent?.({ type: 'log', detail: 'Reached max turns; requesting final report.' });
|
|
56
|
+
messages.push({ role: 'user', content: 'Produce your final report now, without calling any tool.' });
|
|
57
|
+
const final = await adapter.complete({ system, messages, tools: [], signal });
|
|
58
|
+
return { report: final.text, turns: budget.maxTurns, budgetExceeded: true };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,uEAAuE;AACvE,0EAA0E;AAC1E,yCAAyC;AAGzC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQ5C,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAS7B;IACC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3E,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7E,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;QAClD,IAAI,MAAM,EAAE,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;QAEpD,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,GAAG,EAAE,CAAC;YACR,cAAc,GAAG,IAAI,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,gBAAgB,GAAG,sFAAsF;aACnH,CAAC,CAAC;QACL,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7E,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,QAAQ,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QAEzE,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,EAAE,cAAc,EAAE,CAAC;QACpE,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QAE5F,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACtC,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;YACpD,OAAO,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB;gBAAE,OAAO,CAAC,SAAS,EAAE,CAAC;YAE1D,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACrD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,eAAgB,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YACxE,CAAC;YACD,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE;oBACN,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,IAAI,EAAE,IAAI,CAAC,SAAS;oBACpB,MAAM,EAAE,MAAM,CAAC,IAAI;oBACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;iBACjE;aACF,CAAC,CAAC;YACH,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACpG,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,6CAA6C,EAAE,CAAC,CAAC;IAClF,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,0DAA0D,EAAE,CAAC,CAAC;IACrG,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9E,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { LlmToolDef, ProviderAdapter, RunBudget, ToolDispatcher } from '../types.js';
|
|
2
|
+
import { type LoopResult } from './loop.js';
|
|
3
|
+
export type WorkflowSource = {
|
|
4
|
+
kind: 'appq';
|
|
5
|
+
name: string;
|
|
6
|
+
args?: Record<string, unknown>;
|
|
7
|
+
} | {
|
|
8
|
+
kind: 'local';
|
|
9
|
+
path: string;
|
|
10
|
+
};
|
|
11
|
+
export type FetchPromptFn = (name: string, args?: Record<string, unknown>) => Promise<string>;
|
|
12
|
+
export declare function runWorkflow(args: {
|
|
13
|
+
source: WorkflowSource;
|
|
14
|
+
/** Only required when source.kind === 'appq' — pass the calling agent's McpClient.fetchPrompt. */
|
|
15
|
+
fetchPrompt?: FetchPromptFn;
|
|
16
|
+
seedMessage: string;
|
|
17
|
+
tools: LlmToolDef[];
|
|
18
|
+
dispatch: ToolDispatcher;
|
|
19
|
+
adapter: ProviderAdapter;
|
|
20
|
+
budget: RunBudget;
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
onEvent?: (event: {
|
|
23
|
+
type: string;
|
|
24
|
+
detail?: unknown;
|
|
25
|
+
}) => void;
|
|
26
|
+
}): Promise<LoopResult>;
|
|
27
|
+
//# sourceMappingURL=workflowRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflowRunner.d.ts","sourceRoot":"","sources":["../../src/engine/workflowRunner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpC,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAW9F,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,MAAM,EAAE,cAAc,CAAC;IACvB,kGAAkG;IAClG,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/D,GAAG,OAAO,CAAC,UAAU,CAAC,CAetB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Fetches a named workflow (an appq MCP prompt, or a locally-bundled file)
|
|
2
|
+
// and runs it through the generic loop as one fresh-context invocation. This
|
|
3
|
+
// is the one reusable primitive every consuming agent is built around.
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { runLoop } from './loop.js';
|
|
6
|
+
async function resolveWorkflowText(source, fetchPrompt) {
|
|
7
|
+
if (source.kind === 'appq') {
|
|
8
|
+
return fetchPrompt(source.name, source.args ?? {});
|
|
9
|
+
}
|
|
10
|
+
const text = await readFile(source.path, 'utf-8');
|
|
11
|
+
if (!text.trim())
|
|
12
|
+
throw new Error(`Local workflow file "${source.path}" is empty`);
|
|
13
|
+
return text;
|
|
14
|
+
}
|
|
15
|
+
export async function runWorkflow(args) {
|
|
16
|
+
if (args.source.kind === 'appq' && !args.fetchPrompt) {
|
|
17
|
+
throw new Error('runWorkflow() requires fetchPrompt when source.kind is "appq"');
|
|
18
|
+
}
|
|
19
|
+
const system = await resolveWorkflowText(args.source, args.fetchPrompt);
|
|
20
|
+
return runLoop({
|
|
21
|
+
adapter: args.adapter,
|
|
22
|
+
system,
|
|
23
|
+
seedMessage: args.seedMessage,
|
|
24
|
+
tools: args.tools,
|
|
25
|
+
dispatch: args.dispatch,
|
|
26
|
+
budget: args.budget,
|
|
27
|
+
signal: args.signal,
|
|
28
|
+
onEvent: args.onEvent,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=workflowRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflowRunner.js","sourceRoot":"","sources":["../../src/engine/workflowRunner.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,uEAAuE;AAEvE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAmB,MAAM,WAAW,CAAC;AAQrD,KAAK,UAAU,mBAAmB,CAAC,MAAsB,EAAE,WAA0B;IACnF,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,CAAC,IAAI,YAAY,CAAC,CAAC;IACnF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAWjC;IACC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAA4B,CAAC,CAAC;IACzF,OAAO,OAAO,CAAC;QACb,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM;QACN,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
export interface ConsoleEntry {
|
|
3
|
+
type: string;
|
|
4
|
+
text: string;
|
|
5
|
+
timestamp: number;
|
|
6
|
+
}
|
|
7
|
+
export interface NetworkEntry {
|
|
8
|
+
method: string;
|
|
9
|
+
url: string;
|
|
10
|
+
status?: number;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
}
|
|
13
|
+
export interface StepEvidence {
|
|
14
|
+
stepIndex: number;
|
|
15
|
+
action: string;
|
|
16
|
+
screenshotPng: Buffer;
|
|
17
|
+
accessibilitySnapshot: string;
|
|
18
|
+
consoleDeltas: ConsoleEntry[];
|
|
19
|
+
networkDeltas: NetworkEntry[];
|
|
20
|
+
blocked?: {
|
|
21
|
+
reason: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare const DEFAULT_RING_BUFFER_CAP = 500;
|
|
25
|
+
export declare class EvidenceCapture {
|
|
26
|
+
private readonly page;
|
|
27
|
+
private readonly ringBufferCap;
|
|
28
|
+
private console;
|
|
29
|
+
private network;
|
|
30
|
+
private steps;
|
|
31
|
+
private consoleCursor;
|
|
32
|
+
private networkCursor;
|
|
33
|
+
constructor(page: Page, ringBufferCap?: number);
|
|
34
|
+
private push;
|
|
35
|
+
private consumeConsoleDeltas;
|
|
36
|
+
private consumeNetworkDeltas;
|
|
37
|
+
/** Captures a step's evidence bundle: screenshot + a11y snapshot + deltas since the last step. */
|
|
38
|
+
captureStep(stepIndex: number, action: string, blocked?: {
|
|
39
|
+
reason: string;
|
|
40
|
+
}): Promise<StepEvidence>;
|
|
41
|
+
captureFinal(): Promise<Buffer>;
|
|
42
|
+
getSteps(): StepEvidence[];
|
|
43
|
+
/**
|
|
44
|
+
* Console entries logged since the last time this (or captureStep) was
|
|
45
|
+
* called — the direct read path for a browser_console_messages tool,
|
|
46
|
+
* which doesn't need a full step bundle (screenshot + a11y snapshot) just
|
|
47
|
+
* to report deltas. Shares the same cursor as captureStep().
|
|
48
|
+
*/
|
|
49
|
+
getConsoleDeltas(): ConsoleEntry[];
|
|
50
|
+
/** Network entries observed since the last check — see getConsoleDeltas(). */
|
|
51
|
+
getNetworkDeltas(): NetworkEntry[];
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/evidence/capture.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9B;AAED,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,qBAAa,eAAe;IAQxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,aAAa;IARhC,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAK;gBAGP,IAAI,EAAE,IAAI,EACV,aAAa,GAAE,MAAgC;IAmBlE,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,oBAAoB;IAM5B,kGAAkG;IAC5F,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAWnG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAIrC,QAAQ,IAAI,YAAY,EAAE;IAI1B;;;;;OAKG;IACH,gBAAgB,IAAI,YAAY,EAAE;IAIlC,8EAA8E;IAC9E,gBAAgB,IAAI,YAAY,EAAE;CAGnC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Evidence capture via native Playwright/CDP APIs. Deliberately not a port of
|
|
2
|
+
// any browser-extension capture approach (MAIN-world script injection,
|
|
3
|
+
// html2canvas) — those exist only to work around an extension's lack of CDP
|
|
4
|
+
// access to its own tab. A real Playwright session has direct, better access:
|
|
5
|
+
// page.on('console'/'request'/'response'), page.screenshot(),
|
|
6
|
+
// page.accessibility.snapshot().
|
|
7
|
+
export const DEFAULT_RING_BUFFER_CAP = 500;
|
|
8
|
+
export class EvidenceCapture {
|
|
9
|
+
page;
|
|
10
|
+
ringBufferCap;
|
|
11
|
+
console = [];
|
|
12
|
+
network = [];
|
|
13
|
+
steps = [];
|
|
14
|
+
consoleCursor = 0;
|
|
15
|
+
networkCursor = 0;
|
|
16
|
+
constructor(page, ringBufferCap = DEFAULT_RING_BUFFER_CAP) {
|
|
17
|
+
this.page = page;
|
|
18
|
+
this.ringBufferCap = ringBufferCap;
|
|
19
|
+
page.on('console', (msg) => {
|
|
20
|
+
this.push(this.console, { type: msg.type(), text: msg.text(), timestamp: Date.now() });
|
|
21
|
+
});
|
|
22
|
+
page.on('requestfinished', async (req) => {
|
|
23
|
+
const response = await req.response();
|
|
24
|
+
this.push(this.network, {
|
|
25
|
+
method: req.method(),
|
|
26
|
+
url: req.url(),
|
|
27
|
+
status: response?.status(),
|
|
28
|
+
timestamp: Date.now(),
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
page.on('requestfailed', (req) => {
|
|
32
|
+
this.push(this.network, { method: req.method(), url: req.url(), timestamp: Date.now() });
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
push(arr, entry) {
|
|
36
|
+
arr.push(entry);
|
|
37
|
+
if (arr.length > this.ringBufferCap)
|
|
38
|
+
arr.shift();
|
|
39
|
+
}
|
|
40
|
+
consumeConsoleDeltas() {
|
|
41
|
+
const delta = this.console.slice(this.consoleCursor);
|
|
42
|
+
this.consoleCursor = this.console.length;
|
|
43
|
+
return delta;
|
|
44
|
+
}
|
|
45
|
+
consumeNetworkDeltas() {
|
|
46
|
+
const delta = this.network.slice(this.networkCursor);
|
|
47
|
+
this.networkCursor = this.network.length;
|
|
48
|
+
return delta;
|
|
49
|
+
}
|
|
50
|
+
/** Captures a step's evidence bundle: screenshot + a11y snapshot + deltas since the last step. */
|
|
51
|
+
async captureStep(stepIndex, action, blocked) {
|
|
52
|
+
const screenshotPng = await this.page.screenshot({ type: 'png' });
|
|
53
|
+
const accessibilitySnapshot = await this.page.ariaSnapshot({ mode: 'ai' });
|
|
54
|
+
const consoleDeltas = this.consumeConsoleDeltas();
|
|
55
|
+
const networkDeltas = this.consumeNetworkDeltas();
|
|
56
|
+
const entry = { stepIndex, action, screenshotPng, accessibilitySnapshot, consoleDeltas, networkDeltas, blocked };
|
|
57
|
+
this.steps.push(entry);
|
|
58
|
+
return entry;
|
|
59
|
+
}
|
|
60
|
+
async captureFinal() {
|
|
61
|
+
return this.page.screenshot({ type: 'png' });
|
|
62
|
+
}
|
|
63
|
+
getSteps() {
|
|
64
|
+
return this.steps;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Console entries logged since the last time this (or captureStep) was
|
|
68
|
+
* called — the direct read path for a browser_console_messages tool,
|
|
69
|
+
* which doesn't need a full step bundle (screenshot + a11y snapshot) just
|
|
70
|
+
* to report deltas. Shares the same cursor as captureStep().
|
|
71
|
+
*/
|
|
72
|
+
getConsoleDeltas() {
|
|
73
|
+
return this.consumeConsoleDeltas();
|
|
74
|
+
}
|
|
75
|
+
/** Network entries observed since the last check — see getConsoleDeltas(). */
|
|
76
|
+
getNetworkDeltas() {
|
|
77
|
+
return this.consumeNetworkDeltas();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/evidence/capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/evidence/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/evidence/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,uBAAuB,GAIxB,MAAM,cAAc,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './engine/index.js';
|
|
3
|
+
export * from './appq/index.js';
|
|
4
|
+
export * from './providers/index.js';
|
|
5
|
+
export * from './tools/index.js';
|
|
6
|
+
export * from './evidence/index.js';
|
|
7
|
+
export * from './config/index.js';
|
|
8
|
+
export * from './audit/index.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './engine/index.js';
|
|
3
|
+
export * from './appq/index.js';
|
|
4
|
+
export * from './providers/index.js';
|
|
5
|
+
export * from './tools/index.js';
|
|
6
|
+
export * from './evidence/index.js';
|
|
7
|
+
export * from './config/index.js';
|
|
8
|
+
export * from './audit/index.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ProviderAdapter } from '../types.js';
|
|
2
|
+
export declare const DEFAULT_ANTHROPIC_MODEL = "claude-sonnet-5";
|
|
3
|
+
export declare function createAnthropicAdapter(apiKey: string, model?: string, maxTokens?: number): ProviderAdapter;
|
|
4
|
+
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiC,eAAe,EAAE,MAAM,aAAa,CAAC;AAElF,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AA0EzD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAgC,EACvC,SAAS,SAAO,GACf,eAAe,CAgDjB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
export const DEFAULT_ANTHROPIC_MODEL = 'claude-sonnet-5';
|
|
3
|
+
// Prompt caching: the workflow's system prompt and the tool-definition list
|
|
4
|
+
// are static across every turn of the loop, and often identical across many
|
|
5
|
+
// invocations of the same agent — prime candidates for Anthropic's ephemeral
|
|
6
|
+
// cache. The growing message history is also incrementally cached: each turn
|
|
7
|
+
// adds a breakpoint on the last block, so only the newly-added content since
|
|
8
|
+
// the previous turn is charged at full price; everything before it is a
|
|
9
|
+
// cache read.
|
|
10
|
+
const CACHE_CONTROL = { type: 'ephemeral' };
|
|
11
|
+
function toAnthropicMediaType(mimeType) {
|
|
12
|
+
switch (mimeType) {
|
|
13
|
+
case 'image/jpeg':
|
|
14
|
+
case 'image/png':
|
|
15
|
+
case 'image/gif':
|
|
16
|
+
case 'image/webp':
|
|
17
|
+
return mimeType;
|
|
18
|
+
default:
|
|
19
|
+
// Screenshots are always PNG in practice (Playwright's default and
|
|
20
|
+
// what appq's screenshot pipeline stores) — fall back rather than
|
|
21
|
+
// throw on an unexpected content-type from a presigned URL fetch.
|
|
22
|
+
return 'image/png';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function toAnthropicMessages(messages) {
|
|
26
|
+
const out = [];
|
|
27
|
+
for (const m of messages) {
|
|
28
|
+
if (m.role === 'user') {
|
|
29
|
+
out.push({ role: 'user', content: m.content });
|
|
30
|
+
}
|
|
31
|
+
else if (m.role === 'assistant') {
|
|
32
|
+
const blocks = [];
|
|
33
|
+
if (m.content)
|
|
34
|
+
blocks.push({ type: 'text', text: m.content });
|
|
35
|
+
for (const call of m.toolCalls ?? []) {
|
|
36
|
+
blocks.push({ type: 'tool_use', id: call.id, name: call.name, input: call.arguments });
|
|
37
|
+
}
|
|
38
|
+
out.push({ role: 'assistant', content: blocks });
|
|
39
|
+
}
|
|
40
|
+
else if (m.role === 'tool') {
|
|
41
|
+
// Images attached to a tool result go inside the SAME tool_result
|
|
42
|
+
// block, alongside the text — that's the only way Anthropic's API
|
|
43
|
+
// accepts them; a bare image content block outside a tool_result is
|
|
44
|
+
// not valid here. Without this, an "image" is just a URL string in
|
|
45
|
+
// text the model never actually sees.
|
|
46
|
+
const content = m.images?.length
|
|
47
|
+
? [
|
|
48
|
+
{ type: 'text', text: m.content },
|
|
49
|
+
...m.images.map((img) => ({
|
|
50
|
+
type: 'image',
|
|
51
|
+
source: { type: 'base64', media_type: toAnthropicMediaType(img.mimeType), data: img.data },
|
|
52
|
+
})),
|
|
53
|
+
]
|
|
54
|
+
: m.content;
|
|
55
|
+
out.push({
|
|
56
|
+
role: 'user',
|
|
57
|
+
content: [{ type: 'tool_result', tool_use_id: m.toolCallId ?? '', content }],
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Mark the last block of the last message as a cache breakpoint, so the
|
|
62
|
+
// whole prefix built up so far (everything before this turn's new
|
|
63
|
+
// content) is served from cache on the next call instead of re-billed.
|
|
64
|
+
const last = out[out.length - 1];
|
|
65
|
+
if (last && Array.isArray(last.content) && last.content.length > 0) {
|
|
66
|
+
const lastBlock = last.content[last.content.length - 1];
|
|
67
|
+
lastBlock.cache_control = CACHE_CONTROL;
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
export function createAnthropicAdapter(apiKey, model = DEFAULT_ANTHROPIC_MODEL, maxTokens = 4096) {
|
|
72
|
+
const client = new Anthropic({ apiKey });
|
|
73
|
+
return {
|
|
74
|
+
async complete({ system, messages, tools, signal }) {
|
|
75
|
+
const response = await client.messages.create({
|
|
76
|
+
model,
|
|
77
|
+
max_tokens: maxTokens,
|
|
78
|
+
system: [{ type: 'text', text: system, cache_control: CACHE_CONTROL }],
|
|
79
|
+
messages: toAnthropicMessages(messages),
|
|
80
|
+
tools: tools.map((t, i) => ({
|
|
81
|
+
name: t.name,
|
|
82
|
+
description: t.description,
|
|
83
|
+
input_schema: t.inputSchema,
|
|
84
|
+
// Cache breakpoint on the last tool def caches the whole
|
|
85
|
+
// (static, rarely-changing) tools array as one prefix.
|
|
86
|
+
...(i === tools.length - 1 ? { cache_control: CACHE_CONTROL } : {}),
|
|
87
|
+
})),
|
|
88
|
+
}, { signal });
|
|
89
|
+
let text = '';
|
|
90
|
+
const toolCalls = [];
|
|
91
|
+
for (const block of response.content) {
|
|
92
|
+
if (block.type === 'text')
|
|
93
|
+
text += block.text;
|
|
94
|
+
else if (block.type === 'tool_use') {
|
|
95
|
+
toolCalls.push({ id: block.id, name: block.name, arguments: block.input });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
text,
|
|
100
|
+
toolCalls,
|
|
101
|
+
usage: response.usage
|
|
102
|
+
? {
|
|
103
|
+
inputTokens: response.usage.input_tokens,
|
|
104
|
+
outputTokens: response.usage.output_tokens,
|
|
105
|
+
cacheWriteTokens: response.usage.cache_creation_input_tokens ?? undefined,
|
|
106
|
+
cacheReadTokens: response.usage.cache_read_input_tokens ?? undefined,
|
|
107
|
+
}
|
|
108
|
+
: undefined,
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiC,eAAe,EAAE,MAAM,aAAa,CAAC;AAElF,eAAO,MAAM,oBAAoB,UAAU,CAAC;AA0C5C,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAA6B,EACpC,eAAe,SAAO,GACrB,eAAe,CA+CjB"}
|