@almadar/integrations 2.42.0 → 2.43.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/dist/{BaseIntegration-D_iNTesu.d.ts → BaseIntegration-Dgwn1ZR6.d.ts} +2 -0
- package/dist/index.d.ts +12 -7
- package/dist/index.js +41 -8
- package/dist/index.js.map +1 -1
- package/dist/integrations/github/index.d.ts +1 -1
- package/dist/mocks/index.d.ts +1 -1
- package/dist/mocks/index.js +9 -1
- package/dist/mocks/index.js.map +1 -1
- package/dist/runtime/index.d.ts +2 -2
- package/dist/runtime/index.js +41 -8
- package/dist/runtime/index.js.map +1 -1
- package/dist/{store-DcennSSh.d.ts → store-DP3gfEfJ.d.ts} +1 -1
- package/package.json +3 -3
|
@@ -147,6 +147,8 @@ interface IntegrationCallContext {
|
|
|
147
147
|
declare class IntegrationFactory {
|
|
148
148
|
private instances;
|
|
149
149
|
private configs;
|
|
150
|
+
/** Names whose app-wide instance was registered directly (mock infrastructure). */
|
|
151
|
+
private registered;
|
|
150
152
|
/**
|
|
151
153
|
* Configure an integration (doesn't instantiate yet). A `principal` scopes
|
|
152
154
|
* the config to that principal; the app-wide config (no principal) is the
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { e as IntegrationLogger, c as IntegrationErrorCode, a as IntegrationConfig, B as BaseIntegration, d as IntegrationFactory, g as IntegrationParams, h as IntegrationResult, I as IntegrationCallContext } from './BaseIntegration-
|
|
2
|
-
export { b as IntegrationError, f as IntegrationParamValue, U as UnknownActionError, V as ValidationError, i as ValidationResult, j as getIntegrationFactory, r as resetIntegrationFactory, v as validateParams } from './BaseIntegration-
|
|
3
|
-
import { e as CredentialStore, d as CredentialPersistence, H as HookDeclaration } from './store-
|
|
4
|
-
export { A as ArxivActions, C as CLIActions, a as CREDENTIAL_ENTITY_TYPE, b as CREDENTIAL_MASTER_KEY_ENV, c as CredentialEntry, D as DatabaseActions, f as DatabaseDriver, g as DatabaseQueryParamValue, h as DatabaseQueryParams, i as DatabaseQueryResult, j as DatabaseRow, k as DeepAgentActions, l as DockerActions, E as EmailActions, G as GitHubActions, I as IconifyActions, m as IntegrationActionName, n as IntegrationContracts, o as IntegrationName, L as LLMIntegrationActions, M as MLActions, O as OAuthActions, p as OtelActions, Q as QueueActions, R as RedisActions, S as StorageActions, q as StripeActions, T as TwilioActions, W as WebhookActions, r as WikimediaActions, Y as YouTubeActions, s as allCredentialEnvVars, t as declaredCredentialEnvVars, u as serviceHooks } from './store-
|
|
1
|
+
import { e as IntegrationLogger, c as IntegrationErrorCode, a as IntegrationConfig, B as BaseIntegration, d as IntegrationFactory, g as IntegrationParams, h as IntegrationResult, I as IntegrationCallContext } from './BaseIntegration-Dgwn1ZR6.js';
|
|
2
|
+
export { b as IntegrationError, f as IntegrationParamValue, U as UnknownActionError, V as ValidationError, i as ValidationResult, j as getIntegrationFactory, r as resetIntegrationFactory, v as validateParams } from './BaseIntegration-Dgwn1ZR6.js';
|
|
3
|
+
import { e as CredentialStore, d as CredentialPersistence, H as HookDeclaration } from './store-DP3gfEfJ.js';
|
|
4
|
+
export { A as ArxivActions, C as CLIActions, a as CREDENTIAL_ENTITY_TYPE, b as CREDENTIAL_MASTER_KEY_ENV, c as CredentialEntry, D as DatabaseActions, f as DatabaseDriver, g as DatabaseQueryParamValue, h as DatabaseQueryParams, i as DatabaseQueryResult, j as DatabaseRow, k as DeepAgentActions, l as DockerActions, E as EmailActions, G as GitHubActions, I as IconifyActions, m as IntegrationActionName, n as IntegrationContracts, o as IntegrationName, L as LLMIntegrationActions, M as MLActions, O as OAuthActions, p as OtelActions, Q as QueueActions, R as RedisActions, S as StorageActions, q as StripeActions, T as TwilioActions, W as WebhookActions, r as WikimediaActions, Y as YouTubeActions, s as allCredentialEnvVars, t as declaredCredentialEnvVars, u as serviceHooks } from './store-DP3gfEfJ.js';
|
|
5
5
|
import { LogMeta, EntityRow, EventPayload, ServiceHostPorts } from '@almadar/core';
|
|
6
|
-
import { AgentChatMessage, AgentTool,
|
|
6
|
+
import { AgentChatMessage, AgentTool, AgentActivity, ToolCallingClient } from '@almadar/llm';
|
|
7
7
|
export { GitHubIntegration } from './integrations/github/index.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -662,9 +662,14 @@ interface ToolLoopRequest {
|
|
|
662
662
|
instructions?: string;
|
|
663
663
|
maxSteps?: number;
|
|
664
664
|
}
|
|
665
|
+
/** Which model answered, for each `llm_response` step. */
|
|
666
|
+
interface ToolLoopModel {
|
|
667
|
+
provider: string;
|
|
668
|
+
model: string;
|
|
669
|
+
}
|
|
665
670
|
interface ToolLoopResult {
|
|
666
671
|
reply: string;
|
|
667
|
-
steps:
|
|
672
|
+
steps: AgentActivity[];
|
|
668
673
|
usage: {
|
|
669
674
|
promptTokens: number;
|
|
670
675
|
completionTokens: number;
|
|
@@ -672,7 +677,7 @@ interface ToolLoopResult {
|
|
|
672
677
|
modelCalls: number;
|
|
673
678
|
};
|
|
674
679
|
}
|
|
675
|
-
declare function runToolLoop(client: ToolCallingClient, host: ServiceHostPorts, request: ToolLoopRequest): Promise<ToolLoopResult>;
|
|
680
|
+
declare function runToolLoop(client: ToolCallingClient, host: ServiceHostPorts, request: ToolLoopRequest, model: ToolLoopModel, now?: () => number): Promise<ToolLoopResult>;
|
|
676
681
|
|
|
677
682
|
declare class MLIntegration extends BaseIntegration {
|
|
678
683
|
private readonly eventsUrl;
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import webpush from 'web-push';
|
|
|
13
13
|
import { Readable } from 'stream';
|
|
14
14
|
import { getAvailableProvider, LLMClient, EmbeddingClient } from '@almadar/llm';
|
|
15
15
|
import { z } from 'zod';
|
|
16
|
-
import { findInputByAddress, payloadSchemaToJsonSchema, EventPayloadSchema } from '@almadar/core';
|
|
16
|
+
import { traceActivityPayload, findInputByAddress, payloadSchemaToJsonSchema, EventPayloadSchema } from '@almadar/core';
|
|
17
17
|
import { execSync, spawn } from 'child_process';
|
|
18
18
|
import { tmpdir } from 'os';
|
|
19
19
|
import * as oidc from 'openid-client';
|
|
@@ -422,6 +422,8 @@ var IntegrationFactory = class {
|
|
|
422
422
|
constructor() {
|
|
423
423
|
this.instances = /* @__PURE__ */ new Map();
|
|
424
424
|
this.configs = /* @__PURE__ */ new Map();
|
|
425
|
+
/** Names whose app-wide instance was registered directly (mock infrastructure). */
|
|
426
|
+
this.registered = /* @__PURE__ */ new Set();
|
|
425
427
|
}
|
|
426
428
|
/**
|
|
427
429
|
* Configure an integration (doesn't instantiate yet). A `principal` scopes
|
|
@@ -436,7 +438,8 @@ var IntegrationFactory = class {
|
|
|
436
438
|
* back to the app-wide config when no per-principal config exists.
|
|
437
439
|
*/
|
|
438
440
|
get(name, principal) {
|
|
439
|
-
const
|
|
441
|
+
const registered = this.registered.has(name) && !this.configs.has(instanceKey(name, principal));
|
|
442
|
+
const key = registered ? name : instanceKey(name, principal);
|
|
440
443
|
const cached = this.instances.get(key);
|
|
441
444
|
if (cached) {
|
|
442
445
|
return cached;
|
|
@@ -480,6 +483,7 @@ var IntegrationFactory = class {
|
|
|
480
483
|
* Register an integration instance directly (used by mock infrastructure)
|
|
481
484
|
*/
|
|
482
485
|
registerInstance(name, instance, principal) {
|
|
486
|
+
if (principal === void 0) this.registered.add(name);
|
|
483
487
|
this.instances.set(instanceKey(name, principal), instance);
|
|
484
488
|
}
|
|
485
489
|
/**
|
|
@@ -490,8 +494,10 @@ var IntegrationFactory = class {
|
|
|
490
494
|
invalidate(name) {
|
|
491
495
|
if (name === void 0) {
|
|
492
496
|
this.instances.clear();
|
|
497
|
+
this.registered.clear();
|
|
493
498
|
return;
|
|
494
499
|
}
|
|
500
|
+
this.registered.delete(name);
|
|
495
501
|
for (const key of this.instances.keys()) {
|
|
496
502
|
if (key === name || key.startsWith(`${name}\0`)) {
|
|
497
503
|
this.instances.delete(key);
|
|
@@ -503,6 +509,7 @@ var IntegrationFactory = class {
|
|
|
503
509
|
*/
|
|
504
510
|
clear() {
|
|
505
511
|
this.instances.clear();
|
|
512
|
+
this.registered.clear();
|
|
506
513
|
}
|
|
507
514
|
/**
|
|
508
515
|
* Clear all instances and configs
|
|
@@ -510,6 +517,7 @@ var IntegrationFactory = class {
|
|
|
510
517
|
reset() {
|
|
511
518
|
this.instances.clear();
|
|
512
519
|
this.configs.clear();
|
|
520
|
+
this.registered.clear();
|
|
513
521
|
}
|
|
514
522
|
};
|
|
515
523
|
var _factory = null;
|
|
@@ -2513,7 +2521,7 @@ function parseArgs(args) {
|
|
|
2513
2521
|
}
|
|
2514
2522
|
return EventPayloadSchema.safeParse(value);
|
|
2515
2523
|
}
|
|
2516
|
-
async function runToolLoop(client, host, request) {
|
|
2524
|
+
async function runToolLoop(client, host, request, model, now = Date.now) {
|
|
2517
2525
|
const tools = buildTools(host, request.tools);
|
|
2518
2526
|
const defs = [...tools.values()].map((t) => t.def);
|
|
2519
2527
|
const maxSteps = request.maxSteps ?? DEFAULT_MAX_STEPS;
|
|
@@ -2521,10 +2529,17 @@ async function runToolLoop(client, host, request) {
|
|
|
2521
2529
|
...request.instructions !== void 0 ? [{ role: "system", content: request.instructions }] : [],
|
|
2522
2530
|
...request.messages.map((m) => ({ role: m.role, content: m.content }))
|
|
2523
2531
|
];
|
|
2532
|
+
const userPrompt = [...request.messages].reverse().find((m) => m.role === "user")?.content ?? "";
|
|
2524
2533
|
const steps = [];
|
|
2534
|
+
const record = (activity) => {
|
|
2535
|
+
steps.push(activity);
|
|
2536
|
+
host.message(traceActivityPayload(activity));
|
|
2537
|
+
};
|
|
2525
2538
|
const usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0, modelCalls: 0 };
|
|
2526
2539
|
while (usage.modelCalls < maxSteps) {
|
|
2540
|
+
const started = now();
|
|
2527
2541
|
const turn = await client.callWithTools({ messages: conversation, tools: defs });
|
|
2542
|
+
const ended = now();
|
|
2528
2543
|
usage.modelCalls += 1;
|
|
2529
2544
|
if (turn.usage) {
|
|
2530
2545
|
usage.promptTokens += turn.usage.promptTokens;
|
|
@@ -2533,23 +2548,41 @@ async function runToolLoop(client, host, request) {
|
|
|
2533
2548
|
}
|
|
2534
2549
|
conversation.push(turn.message);
|
|
2535
2550
|
const calls = turn.message.tool_calls ?? [];
|
|
2551
|
+
record({
|
|
2552
|
+
type: "llm_response",
|
|
2553
|
+
content: turn.message.content ?? "",
|
|
2554
|
+
llm: {
|
|
2555
|
+
service: "llm",
|
|
2556
|
+
provider: model.provider,
|
|
2557
|
+
model: model.model,
|
|
2558
|
+
systemPrompt: request.instructions ?? "",
|
|
2559
|
+
userPrompt,
|
|
2560
|
+
...calls.length > 0 ? { toolCallsJson: JSON.stringify(calls) } : {},
|
|
2561
|
+
durationMs: ended - started,
|
|
2562
|
+
...turn.usage ? { promptTokens: turn.usage.promptTokens, completionTokens: turn.usage.completionTokens } : {}
|
|
2563
|
+
},
|
|
2564
|
+
timestamp: ended
|
|
2565
|
+
});
|
|
2536
2566
|
if (calls.length === 0) return { reply: turn.message.content ?? "", steps, usage };
|
|
2537
2567
|
for (const call of calls) {
|
|
2538
2568
|
const args = call.function.arguments;
|
|
2539
2569
|
const tool = tools.get(call.function.name);
|
|
2570
|
+
const kind = tool === void 0 ? "invalid" : tool.target.kind;
|
|
2571
|
+
const label = tool === void 0 ? call.function.name : tool.target.kind === "input" ? tool.target.address : tool.target.entity;
|
|
2572
|
+
record({ type: "tool_call", tool: label, kind, argsText: args, timestamp: now() });
|
|
2540
2573
|
let content;
|
|
2541
2574
|
if (!tool) {
|
|
2542
|
-
steps.push({ kind: "invalid", target: call.function.name, args, ok: false, detail: "not an allowed tool" });
|
|
2543
2575
|
content = JSON.stringify({ error: `'${call.function.name}' is not one of your tools` });
|
|
2576
|
+
record({ type: "tool_result", tool: label, kind, success: false, detail: "not an allowed tool", resultText: content, timestamp: now() });
|
|
2544
2577
|
} else if (tool.target.kind === "read") {
|
|
2545
2578
|
const rows = await host.read(tool.target.entity);
|
|
2546
|
-
steps.push({ kind: "read", target: tool.target.entity, args, ok: true });
|
|
2547
2579
|
content = JSON.stringify({ rows });
|
|
2580
|
+
record({ type: "tool_result", tool: label, kind, success: true, rows: rows.length, resultText: content, timestamp: now() });
|
|
2548
2581
|
} else {
|
|
2549
2582
|
const parsed = parseArgs(args);
|
|
2550
2583
|
if (!parsed.success) {
|
|
2551
|
-
steps.push({ kind: "input", target: tool.target.address, args, ok: false, detail: "arguments are not a JSON object" });
|
|
2552
2584
|
content = JSON.stringify({ error: "arguments must be a JSON object" });
|
|
2585
|
+
record({ type: "tool_result", tool: label, kind, success: false, detail: "arguments are not a JSON object", resultText: content, timestamp: now() });
|
|
2553
2586
|
} else {
|
|
2554
2587
|
const { input } = tool.target;
|
|
2555
2588
|
const response = await host.dispatchInput(input.orbital, {
|
|
@@ -2558,8 +2591,8 @@ async function runToolLoop(client, host, request) {
|
|
|
2558
2591
|
payload: parsed.data
|
|
2559
2592
|
});
|
|
2560
2593
|
const detail = dispatchFailure(response);
|
|
2561
|
-
steps.push({ kind: "input", target: tool.target.address, args, ok: detail === void 0, ...detail !== void 0 ? { detail } : {} });
|
|
2562
2594
|
content = JSON.stringify(response);
|
|
2595
|
+
record({ type: "tool_result", tool: label, kind, success: detail === void 0, ...detail !== void 0 ? { detail } : {}, resultText: content, timestamp: now() });
|
|
2563
2596
|
}
|
|
2564
2597
|
}
|
|
2565
2598
|
conversation.push({ role: "tool", content, tool_call_id: call.id });
|
|
@@ -2738,7 +2771,7 @@ Return ONLY valid JSON matching the schema.`,
|
|
|
2738
2771
|
}
|
|
2739
2772
|
const request = CallToolsParamsSchema.parse(params);
|
|
2740
2773
|
const client = request.model !== void 0 ? new LLMClient({ provider: this.provider, model: request.model }) : this.getClient();
|
|
2741
|
-
return runToolLoop(client, context.host, request);
|
|
2774
|
+
return runToolLoop(client, context.host, request, { provider: client.getProvider(), model: client.getModelName() });
|
|
2742
2775
|
}
|
|
2743
2776
|
async embed(params) {
|
|
2744
2777
|
const { texts } = params;
|