@desplega.ai/agent-swarm 1.92.2 → 1.93.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/openapi.json +63 -3
- package/package.json +5 -5
- package/src/be/db.ts +91 -6
- package/src/be/memory/boot-reembed.ts +0 -1
- package/src/be/memory/providers/sqlite-store.ts +42 -25
- package/src/be/memory/raters/llm-client.ts +12 -5
- package/src/be/memory/types.ts +3 -0
- package/src/be/migrations/088_script_runs_list_indexes.sql +10 -0
- package/src/be/migrations/089_harness_variant.sql +2 -0
- package/src/be/modelsdev-cache.json +1222 -986
- package/src/be/seed-pricing.ts +1 -0
- package/src/be/seed-scripts/catalog/boot-triage.inline.ts +221 -0
- package/src/be/seed-scripts/catalog/catalog-report.inline.ts +457 -0
- package/src/be/seed-scripts/catalog/compound-insights.inline.ts +863 -0
- package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +506 -0
- package/src/be/seed-scripts/index.ts +5 -5
- package/src/be/skill-sync.ts +28 -179
- package/src/commands/runner.ts +124 -7
- package/src/http/api-keys.ts +42 -0
- package/src/http/mcp-bridge.ts +1 -1
- package/src/http/memory.ts +23 -24
- package/src/http/tasks.ts +10 -6
- package/src/providers/claude-adapter.ts +33 -1
- package/src/providers/claude-managed-adapter.ts +3 -0
- package/src/providers/claude-managed-models.ts +7 -0
- package/src/providers/codex-adapter.ts +8 -1
- package/src/providers/codex-models.ts +1 -0
- package/src/providers/codex-oauth/auth-json.ts +1 -0
- package/src/providers/harness-version.ts +7 -0
- package/src/providers/opencode-adapter.ts +11 -4
- package/src/providers/pi-mono-adapter.ts +12 -2
- package/src/providers/types.ts +2 -0
- package/src/scripts-runtime/egress-secrets.ts +83 -0
- package/src/scripts-runtime/eval-harness.ts +4 -0
- package/src/scripts-runtime/executors/types.ts +7 -0
- package/src/scripts-runtime/loader.ts +2 -0
- package/src/server-user.ts +2 -2
- package/src/slack/channel-join.ts +41 -0
- package/src/tests/additive-buffer.test.ts +0 -1
- package/src/tests/api-key-tracking.test.ts +113 -0
- package/src/tests/approval-requests.test.ts +0 -6
- package/src/tests/claude-managed-setup.test.ts +0 -4
- package/src/tests/codex-pool.test.ts +2 -6
- package/src/tests/http-api-integration.test.ts +4 -6
- package/src/tests/memory-edges.test.ts +0 -2
- package/src/tests/memory-rate-endpoint.test.ts +0 -2
- package/src/tests/memory-rater-e2e.test.ts +0 -2
- package/src/tests/memory-store.test.ts +19 -1
- package/src/tests/memory.test.ts +51 -0
- package/src/tests/model-control.test.ts +1 -1
- package/src/tests/reload-config.test.ts +33 -17
- package/src/tests/runner-skills-refresh.test.ts +216 -46
- package/src/tests/script-runs-http.test.ts +7 -1
- package/src/tests/scripts-runtime-secret-egress.test.ts +129 -0
- package/src/tests/seed-scripts.test.ts +13 -1
- package/src/tests/session-attach.test.ts +6 -6
- package/src/tests/skill-fs-writer.test.ts +250 -0
- package/src/tests/slack-attachments-block.test.ts +0 -1
- package/src/tests/slack-blocks.test.ts +0 -1
- package/src/tests/slack-channel-join.test.ts +80 -0
- package/src/tests/slack-identity-resolution.test.ts +0 -1
- package/src/tests/structured-output.test.ts +0 -2
- package/src/tests/use-dismissible-card.test.ts +0 -4
- package/src/tools/schedules/create-schedule.ts +2 -2
- package/src/tools/schedules/update-schedule.ts +1 -1
- package/src/tools/send-task.ts +2 -2
- package/src/tools/slack-post.ts +18 -15
- package/src/tools/slack-read.ts +9 -11
- package/src/tools/slack-reply.ts +18 -15
- package/src/tools/slack-start-thread.ts +17 -14
- package/src/tools/task-action.ts +2 -2
- package/src/types.ts +11 -0
- package/src/utils/context-window.ts +3 -0
- package/src/utils/credentials.ts +22 -2
- package/src/utils/skill-fs-writer.ts +220 -0
- package/src/utils/skills-refresh.ts +123 -40
package/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Agent Swarm API",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.93.0",
|
|
6
6
|
"description": "Multi-agent orchestration API for Claude Code, Codex, and Gemini CLI. Enables task distribution, agent communication, and service discovery.\n\nMCP tools are documented separately in [MCP.md](./MCP.md)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
@@ -2740,6 +2740,59 @@
|
|
|
2740
2740
|
}
|
|
2741
2741
|
}
|
|
2742
2742
|
},
|
|
2743
|
+
"/api/keys/clear-rate-limit": {
|
|
2744
|
+
"post": {
|
|
2745
|
+
"summary": "Clear rate-limited status for a key after a successful use proves it is healthy",
|
|
2746
|
+
"tags": [
|
|
2747
|
+
"API Keys"
|
|
2748
|
+
],
|
|
2749
|
+
"security": [
|
|
2750
|
+
{
|
|
2751
|
+
"bearerAuth": []
|
|
2752
|
+
}
|
|
2753
|
+
],
|
|
2754
|
+
"requestBody": {
|
|
2755
|
+
"content": {
|
|
2756
|
+
"application/json": {
|
|
2757
|
+
"schema": {
|
|
2758
|
+
"type": "object",
|
|
2759
|
+
"properties": {
|
|
2760
|
+
"keyType": {
|
|
2761
|
+
"type": "string"
|
|
2762
|
+
},
|
|
2763
|
+
"keySuffix": {
|
|
2764
|
+
"type": "string",
|
|
2765
|
+
"minLength": 1,
|
|
2766
|
+
"maxLength": 10
|
|
2767
|
+
},
|
|
2768
|
+
"scope": {
|
|
2769
|
+
"type": "string"
|
|
2770
|
+
},
|
|
2771
|
+
"scopeId": {
|
|
2772
|
+
"type": "string"
|
|
2773
|
+
}
|
|
2774
|
+
},
|
|
2775
|
+
"required": [
|
|
2776
|
+
"keyType",
|
|
2777
|
+
"keySuffix"
|
|
2778
|
+
]
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
},
|
|
2783
|
+
"responses": {
|
|
2784
|
+
"200": {
|
|
2785
|
+
"description": "Rate limit cleared (or key was not rate-limited)"
|
|
2786
|
+
},
|
|
2787
|
+
"400": {
|
|
2788
|
+
"description": "Validation error"
|
|
2789
|
+
},
|
|
2790
|
+
"401": {
|
|
2791
|
+
"description": "Unauthorized"
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
},
|
|
2743
2796
|
"/api/events": {
|
|
2744
2797
|
"post": {
|
|
2745
2798
|
"summary": "Store a single event",
|
|
@@ -10711,9 +10764,9 @@
|
|
|
10711
10764
|
}
|
|
10712
10765
|
}
|
|
10713
10766
|
},
|
|
10714
|
-
"/api/tasks/{id}/
|
|
10767
|
+
"/api/tasks/{id}/session": {
|
|
10715
10768
|
"put": {
|
|
10716
|
-
"summary": "Update
|
|
10769
|
+
"summary": "Update provider session ID and harness metadata for a task",
|
|
10717
10770
|
"tags": [
|
|
10718
10771
|
"Tasks"
|
|
10719
10772
|
],
|
|
@@ -10800,6 +10853,13 @@
|
|
|
10800
10853
|
"providerMeta": {
|
|
10801
10854
|
"type": "object",
|
|
10802
10855
|
"properties": {}
|
|
10856
|
+
},
|
|
10857
|
+
"harnessVariant": {
|
|
10858
|
+
"type": "string"
|
|
10859
|
+
},
|
|
10860
|
+
"harnessVariantMeta": {
|
|
10861
|
+
"type": "object",
|
|
10862
|
+
"additionalProperties": {}
|
|
10803
10863
|
}
|
|
10804
10864
|
},
|
|
10805
10865
|
"required": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@desplega.ai/agent-swarm",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.93.0",
|
|
4
4
|
"description": "Multi-agent orchestration for Claude Code, Codex, Gemini CLI, and other AI coding assistants",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "desplega.sh <contact@desplega.sh>",
|
|
@@ -112,11 +112,11 @@
|
|
|
112
112
|
"@desplega.ai/localtunnel": "^2.2.0",
|
|
113
113
|
"@inkjs/ui": "^2.0.0",
|
|
114
114
|
"@linear/sdk": "^77.0.0",
|
|
115
|
-
"@earendil-works/pi-agent-core": "^0.
|
|
116
|
-
"@earendil-works/pi-ai": "^0.
|
|
117
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
115
|
+
"@earendil-works/pi-agent-core": "^0.79.1",
|
|
116
|
+
"@earendil-works/pi-ai": "^0.79.1",
|
|
117
|
+
"@earendil-works/pi-coding-agent": "^0.79.1",
|
|
118
118
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
119
|
-
"@openai/codex-sdk": "^0.
|
|
119
|
+
"@openai/codex-sdk": "^0.139.0",
|
|
120
120
|
"@opencode-ai/sdk": "^1.16.2",
|
|
121
121
|
"@openfort/openfort-node": "^0.9.1",
|
|
122
122
|
"@opentelemetry/api": "^1.9.1",
|
package/src/be/db.ts
CHANGED
|
@@ -65,6 +65,7 @@ import type {
|
|
|
65
65
|
ScriptRun,
|
|
66
66
|
ScriptRunJournalEntry,
|
|
67
67
|
ScriptRunKind,
|
|
68
|
+
ScriptRunListItem,
|
|
68
69
|
ScriptRunStatus,
|
|
69
70
|
Service,
|
|
70
71
|
ServiceStatus,
|
|
@@ -1041,6 +1042,8 @@ type AgentTaskRow = {
|
|
|
1041
1042
|
swarmVersion: string | null;
|
|
1042
1043
|
provider: string | null;
|
|
1043
1044
|
providerMeta: string | null;
|
|
1045
|
+
harnessVariant: string | null;
|
|
1046
|
+
harnessVariantMeta: string | null;
|
|
1044
1047
|
totalCostUsd?: number | null;
|
|
1045
1048
|
};
|
|
1046
1049
|
|
|
@@ -1102,7 +1105,7 @@ function rowToAgentTask(row: AgentTaskRow): AgentTask {
|
|
|
1102
1105
|
dir: row.dir ?? undefined,
|
|
1103
1106
|
parentTaskId: row.parentTaskId ?? undefined,
|
|
1104
1107
|
claudeSessionId: row.claudeSessionId ?? undefined,
|
|
1105
|
-
model: (row.model as "haiku" | "sonnet" | "opus" | null) ?? undefined,
|
|
1108
|
+
model: (row.model as "haiku" | "sonnet" | "opus" | "fable" | null) ?? undefined,
|
|
1106
1109
|
scheduleId: row.scheduleId ?? undefined,
|
|
1107
1110
|
workflowRunId: row.workflowRunId ?? undefined,
|
|
1108
1111
|
workflowRunStepId: row.workflowRunStepId ?? undefined,
|
|
@@ -1127,6 +1130,8 @@ function rowToAgentTask(row: AgentTaskRow): AgentTask {
|
|
|
1127
1130
|
swarmVersion: row.swarmVersion ?? undefined,
|
|
1128
1131
|
provider: (row.provider as ProviderName | null) ?? undefined,
|
|
1129
1132
|
providerMeta: parseProviderMeta(row.provider as ProviderName | null, row.providerMeta),
|
|
1133
|
+
harnessVariant: row.harnessVariant ?? undefined,
|
|
1134
|
+
harnessVariantMeta: row.harnessVariantMeta ? JSON.parse(row.harnessVariantMeta) : undefined,
|
|
1130
1135
|
totalCostUsd: row.totalCostUsd ?? undefined,
|
|
1131
1136
|
};
|
|
1132
1137
|
}
|
|
@@ -1398,6 +1403,8 @@ export function updateTaskClaudeSessionId(
|
|
|
1398
1403
|
provider?: ProviderName,
|
|
1399
1404
|
providerMeta?: Record<string, unknown>,
|
|
1400
1405
|
model?: string,
|
|
1406
|
+
harnessVariant?: string,
|
|
1407
|
+
harnessVariantMeta?: Record<string, unknown>,
|
|
1401
1408
|
): AgentTask | null {
|
|
1402
1409
|
const setClauses = ["claudeSessionId = ?", "lastUpdatedAt = ?"];
|
|
1403
1410
|
const params: (string | null)[] = [claudeSessionId, new Date().toISOString()];
|
|
@@ -1414,6 +1421,14 @@ export function updateTaskClaudeSessionId(
|
|
|
1414
1421
|
setClauses.push("model = ?");
|
|
1415
1422
|
params.push(model);
|
|
1416
1423
|
}
|
|
1424
|
+
if (harnessVariant !== undefined) {
|
|
1425
|
+
setClauses.push("harnessVariant = ?");
|
|
1426
|
+
params.push(harnessVariant);
|
|
1427
|
+
}
|
|
1428
|
+
if (harnessVariantMeta !== undefined) {
|
|
1429
|
+
setClauses.push("harnessVariantMeta = ?");
|
|
1430
|
+
params.push(JSON.stringify(harnessVariantMeta));
|
|
1431
|
+
}
|
|
1417
1432
|
|
|
1418
1433
|
params.push(taskId);
|
|
1419
1434
|
|
|
@@ -5291,7 +5306,7 @@ function rowToScheduledTask(row: ScheduledTaskRow): ScheduledTask {
|
|
|
5291
5306
|
consecutiveErrors: row.consecutiveErrors ?? 0,
|
|
5292
5307
|
lastErrorAt: normalizeDate(row.lastErrorAt) ?? undefined,
|
|
5293
5308
|
lastErrorMessage: row.lastErrorMessage ?? undefined,
|
|
5294
|
-
model: (row.model as "haiku" | "sonnet" | "opus" | null) ?? undefined,
|
|
5309
|
+
model: (row.model as "haiku" | "sonnet" | "opus" | "fable" | null) ?? undefined,
|
|
5295
5310
|
scheduleType: row.scheduleType as "recurring" | "one_time",
|
|
5296
5311
|
createdAt: normalizeDateRequired(row.createdAt),
|
|
5297
5312
|
lastUpdatedAt: normalizeDateRequired(row.lastUpdatedAt),
|
|
@@ -10058,6 +10073,28 @@ export function setApiKeyName(
|
|
|
10058
10073
|
return result.changes > 0;
|
|
10059
10074
|
}
|
|
10060
10075
|
|
|
10076
|
+
/**
|
|
10077
|
+
* Clear a stale rate-limit record after a successful use proves the key is healthy.
|
|
10078
|
+
*/
|
|
10079
|
+
export function clearKeyRateLimit(
|
|
10080
|
+
keyType: string,
|
|
10081
|
+
keySuffix: string,
|
|
10082
|
+
scope = "global",
|
|
10083
|
+
scopeId: string | null = null,
|
|
10084
|
+
): boolean {
|
|
10085
|
+
const now = new Date().toISOString();
|
|
10086
|
+
const effectiveScopeId = scopeId ?? "";
|
|
10087
|
+
const result = getDb()
|
|
10088
|
+
.prepare(
|
|
10089
|
+
`UPDATE api_key_status
|
|
10090
|
+
SET status = 'available', rateLimitedUntil = NULL, updatedAt = ?
|
|
10091
|
+
WHERE keyType = ? AND keySuffix = ? AND scope = ? AND scopeId = ?
|
|
10092
|
+
AND status = 'rate_limited'`,
|
|
10093
|
+
)
|
|
10094
|
+
.run(now, keyType, keySuffix, scope, effectiveScopeId);
|
|
10095
|
+
return result.changes > 0;
|
|
10096
|
+
}
|
|
10097
|
+
|
|
10061
10098
|
/**
|
|
10062
10099
|
* Get all key status records for a credential type.
|
|
10063
10100
|
*/
|
|
@@ -11574,6 +11611,22 @@ type ScriptRunRow = {
|
|
|
11574
11611
|
updated_by: string | null;
|
|
11575
11612
|
};
|
|
11576
11613
|
|
|
11614
|
+
type ScriptRunListRow = Pick<
|
|
11615
|
+
ScriptRunRow,
|
|
11616
|
+
| "id"
|
|
11617
|
+
| "agentId"
|
|
11618
|
+
| "scriptName"
|
|
11619
|
+
| "kind"
|
|
11620
|
+
| "status"
|
|
11621
|
+
| "pid"
|
|
11622
|
+
| "startedAt"
|
|
11623
|
+
| "finishedAt"
|
|
11624
|
+
| "error"
|
|
11625
|
+
| "last_heartbeat_at"
|
|
11626
|
+
| "idempotencyKey"
|
|
11627
|
+
| "requestedByUserId"
|
|
11628
|
+
>;
|
|
11629
|
+
|
|
11577
11630
|
function parseJsonColumn(value: string | null): unknown | undefined {
|
|
11578
11631
|
if (value === null) return undefined;
|
|
11579
11632
|
return JSON.parse(value);
|
|
@@ -11599,6 +11652,23 @@ function rowToScriptRun(row: ScriptRunRow): ScriptRun {
|
|
|
11599
11652
|
};
|
|
11600
11653
|
}
|
|
11601
11654
|
|
|
11655
|
+
function rowToScriptRunListItem(row: ScriptRunListRow): ScriptRunListItem {
|
|
11656
|
+
return {
|
|
11657
|
+
id: row.id,
|
|
11658
|
+
agentId: row.agentId,
|
|
11659
|
+
scriptName: row.scriptName ?? undefined,
|
|
11660
|
+
kind: row.kind as ScriptRunKind,
|
|
11661
|
+
status: row.status as ScriptRunStatus,
|
|
11662
|
+
pid: row.pid ?? undefined,
|
|
11663
|
+
startedAt: row.startedAt,
|
|
11664
|
+
finishedAt: row.finishedAt ?? undefined,
|
|
11665
|
+
error: row.error ?? undefined,
|
|
11666
|
+
lastHeartbeatAt: row.last_heartbeat_at ?? undefined,
|
|
11667
|
+
idempotencyKey: row.idempotencyKey ?? undefined,
|
|
11668
|
+
requestedByUserId: row.requestedByUserId ?? undefined,
|
|
11669
|
+
};
|
|
11670
|
+
}
|
|
11671
|
+
|
|
11602
11672
|
export function createScriptRun(data: {
|
|
11603
11673
|
id: string;
|
|
11604
11674
|
agentId: string;
|
|
@@ -11733,7 +11803,7 @@ export function listScriptRuns(opts?: {
|
|
|
11733
11803
|
agentId?: string;
|
|
11734
11804
|
limit?: number;
|
|
11735
11805
|
offset?: number;
|
|
11736
|
-
}):
|
|
11806
|
+
}): ScriptRunListItem[] {
|
|
11737
11807
|
const conditions: string[] = [];
|
|
11738
11808
|
const params: Array<string | number> = [];
|
|
11739
11809
|
if (opts?.status) {
|
|
@@ -11750,11 +11820,26 @@ export function listScriptRuns(opts?: {
|
|
|
11750
11820
|
params.push(limit, offset);
|
|
11751
11821
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
11752
11822
|
const rows = getDb()
|
|
11753
|
-
.prepare<
|
|
11754
|
-
`SELECT
|
|
11823
|
+
.prepare<ScriptRunListRow, Array<string | number>>(
|
|
11824
|
+
`SELECT
|
|
11825
|
+
id,
|
|
11826
|
+
agentId,
|
|
11827
|
+
scriptName,
|
|
11828
|
+
kind,
|
|
11829
|
+
status,
|
|
11830
|
+
pid,
|
|
11831
|
+
startedAt,
|
|
11832
|
+
finishedAt,
|
|
11833
|
+
error,
|
|
11834
|
+
last_heartbeat_at,
|
|
11835
|
+
idempotencyKey,
|
|
11836
|
+
requestedByUserId
|
|
11837
|
+
FROM script_runs ${where}
|
|
11838
|
+
ORDER BY startedAt DESC
|
|
11839
|
+
LIMIT ? OFFSET ?`,
|
|
11755
11840
|
)
|
|
11756
11841
|
.all(...params);
|
|
11757
|
-
return rows.map(
|
|
11842
|
+
return rows.map(rowToScriptRunListItem);
|
|
11758
11843
|
}
|
|
11759
11844
|
|
|
11760
11845
|
export function countScriptRuns(opts?: { status?: ScriptRunStatus; agentId?: string }): number {
|
|
@@ -13,7 +13,6 @@ import { getEmbeddingProvider, getMemoryStore } from "./index";
|
|
|
13
13
|
|
|
14
14
|
const VECTOR_BYTES = EMBEDDING_DIMENSIONS * Float32Array.BYTES_PER_ELEMENT;
|
|
15
15
|
const BATCH_SIZE = 20;
|
|
16
|
-
const BACKFILL_KV_KEY = "memory:reembed:backfill_complete";
|
|
17
16
|
|
|
18
17
|
export async function runBootReembed(): Promise<void> {
|
|
19
18
|
const db = getDb();
|
|
@@ -488,29 +488,19 @@ export class SqliteMemoryStore implements MemoryStore {
|
|
|
488
488
|
}
|
|
489
489
|
}
|
|
490
490
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
491
|
+
private buildListWhereClause(
|
|
492
|
+
agentId: string,
|
|
493
|
+
options: MemoryListOptions,
|
|
494
|
+
): { whereClause: string; params: (Buffer | string | number | null)[] } {
|
|
495
|
+
const { scope = "all", isLead = false, ownerAgentId, source, sourcePath } = options;
|
|
495
496
|
const conditions: string[] = [];
|
|
496
|
-
const params: (string | number)[] = [];
|
|
497
|
+
const params: (Buffer | string | number | null)[] = [];
|
|
497
498
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
conditions.push("scope = 'swarm'");
|
|
504
|
-
} else {
|
|
505
|
-
conditions.push("(agentId = ? OR scope = 'swarm')");
|
|
506
|
-
params.push(agentId);
|
|
507
|
-
}
|
|
508
|
-
} else {
|
|
509
|
-
if (scope === "agent") {
|
|
510
|
-
conditions.push("scope = 'agent'");
|
|
511
|
-
} else if (scope === "swarm") {
|
|
512
|
-
conditions.push("scope = 'swarm'");
|
|
513
|
-
}
|
|
499
|
+
this.addScopeConditions(conditions, params, agentId, scope, isLead);
|
|
500
|
+
|
|
501
|
+
if (ownerAgentId) {
|
|
502
|
+
conditions.push("agentId = ?");
|
|
503
|
+
params.push(ownerAgentId);
|
|
514
504
|
}
|
|
515
505
|
|
|
516
506
|
if (source) {
|
|
@@ -518,18 +508,45 @@ export class SqliteMemoryStore implements MemoryStore {
|
|
|
518
508
|
params.push(source);
|
|
519
509
|
}
|
|
520
510
|
|
|
521
|
-
const
|
|
522
|
-
|
|
511
|
+
const sourcePathNeedle = sourcePath?.trim().toLowerCase();
|
|
512
|
+
if (sourcePathNeedle) {
|
|
513
|
+
conditions.push("instr(lower(coalesce(sourcePath, '')), ?) > 0");
|
|
514
|
+
params.push(sourcePathNeedle);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
return {
|
|
518
|
+
whereClause: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
|
|
519
|
+
params,
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
list(agentId: string, options: MemoryListOptions = {}): AgentMemory[] {
|
|
524
|
+
const { limit = 20, offset = 0 } = options;
|
|
525
|
+
const db = getDb();
|
|
526
|
+
const { whereClause, params } = this.buildListWhereClause(agentId, options);
|
|
527
|
+
const queryParams = [...params, limit, offset];
|
|
523
528
|
|
|
524
529
|
const rows = db
|
|
525
|
-
.prepare<AgentMemoryRow, (string | number)[]>(
|
|
530
|
+
.prepare<AgentMemoryRow, (Buffer | string | number | null)[]>(
|
|
526
531
|
`SELECT * FROM agent_memory ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
|
|
527
532
|
)
|
|
528
|
-
.all(...
|
|
533
|
+
.all(...queryParams);
|
|
529
534
|
|
|
530
535
|
return rows.map(rowToAgentMemory);
|
|
531
536
|
}
|
|
532
537
|
|
|
538
|
+
count(agentId: string, options: MemoryListOptions = {}): number {
|
|
539
|
+
const db = getDb();
|
|
540
|
+
const { whereClause, params } = this.buildListWhereClause(agentId, options);
|
|
541
|
+
const row = db
|
|
542
|
+
.prepare<{ count: number }, (Buffer | string | number | null)[]>(
|
|
543
|
+
`SELECT COUNT(*) AS count FROM agent_memory ${whereClause}`,
|
|
544
|
+
)
|
|
545
|
+
.get(...params);
|
|
546
|
+
|
|
547
|
+
return row?.count ?? 0;
|
|
548
|
+
}
|
|
549
|
+
|
|
533
550
|
isSourceProtected(source: AgentMemorySource): boolean {
|
|
534
551
|
return PROTECTED_SOURCES.has(source);
|
|
535
552
|
}
|
|
@@ -75,6 +75,13 @@ AGENT RESPONSE / SUMMARY:
|
|
|
75
75
|
|
|
76
76
|
Score 0..1.`;
|
|
77
77
|
|
|
78
|
+
const PLACEHOLDER_PREFIX = "$";
|
|
79
|
+
const QUERY_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{query}`;
|
|
80
|
+
const MEMORY_ID_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{memoryId}`;
|
|
81
|
+
const MEMORY_NAME_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{memoryName}`;
|
|
82
|
+
const MEMORY_CONTENT_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{memoryContent}`;
|
|
83
|
+
const RESPONSE_PLACEHOLDER = `${PLACEHOLDER_PREFIX}{response}`;
|
|
84
|
+
|
|
78
85
|
/**
|
|
79
86
|
* `claude -p --output-format json` returns a JSON envelope of the shape
|
|
80
87
|
* `{ result: string, ... }`. We parse the envelope, then JSON-parse the
|
|
@@ -83,11 +90,11 @@ Score 0..1.`;
|
|
|
83
90
|
type ClaudeCliEnvelope = { result?: unknown };
|
|
84
91
|
|
|
85
92
|
function buildPrompt(input: LlmRaterInput): string {
|
|
86
|
-
return PROMPT_TEMPLATE.replace(
|
|
87
|
-
.replace(
|
|
88
|
-
.replace(
|
|
89
|
-
.replace(
|
|
90
|
-
.replace(
|
|
93
|
+
return PROMPT_TEMPLATE.replace(QUERY_PLACEHOLDER, input.query)
|
|
94
|
+
.replace(MEMORY_ID_PLACEHOLDER, input.memory.id)
|
|
95
|
+
.replace(MEMORY_NAME_PLACEHOLDER, input.memory.name)
|
|
96
|
+
.replace(MEMORY_CONTENT_PLACEHOLDER, input.memory.content)
|
|
97
|
+
.replace(RESPONSE_PLACEHOLDER, input.response);
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
function parseScoreAndReasoning(raw: unknown): LlmRaterResult | null {
|
package/src/be/memory/types.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface MemoryStore {
|
|
|
22
22
|
peek(id: string): AgentMemory | null;
|
|
23
23
|
search(embedding: Float32Array, agentId: string, options: MemorySearchOptions): MemoryCandidate[];
|
|
24
24
|
list(agentId: string, options: MemoryListOptions): AgentMemory[];
|
|
25
|
+
count(agentId: string, options: MemoryListOptions): number;
|
|
25
26
|
isSourceProtected(source: AgentMemorySource): boolean;
|
|
26
27
|
listForCuration(
|
|
27
28
|
agentId?: string,
|
|
@@ -80,7 +81,9 @@ export interface MemoryListOptions {
|
|
|
80
81
|
limit?: number;
|
|
81
82
|
offset?: number;
|
|
82
83
|
isLead?: boolean;
|
|
84
|
+
ownerAgentId?: string;
|
|
83
85
|
source?: AgentMemorySource;
|
|
86
|
+
sourcePath?: string;
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
export interface MemoryStats {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- Keep script run list pages fast as historical rows accumulate.
|
|
2
|
+
|
|
3
|
+
CREATE INDEX IF NOT EXISTS idx_script_runs_startedAt
|
|
4
|
+
ON script_runs(startedAt DESC);
|
|
5
|
+
|
|
6
|
+
CREATE INDEX IF NOT EXISTS idx_script_runs_status_startedAt
|
|
7
|
+
ON script_runs(status, startedAt DESC);
|
|
8
|
+
|
|
9
|
+
CREATE INDEX IF NOT EXISTS idx_script_runs_agentId_startedAt
|
|
10
|
+
ON script_runs(agentId, startedAt DESC);
|