@desplega.ai/agent-swarm 1.157.0 → 1.158.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/{acp-adapter-qhqrk4q0.js → acp-adapter-xaq4n6pc.js} +1 -1
- package/dist/{actions-9rrg0zxm.js → actions-p9hz5yat.js} +15 -15
- package/dist/{app-enysy1zd.js → app-g26wdcz6.js} +4 -4
- package/dist/{artifact-td4q4dch.js → artifact-3v5t9jtg.js} +1 -1
- package/dist/{assistant-zegamy48.js → assistant-wydfqkb3.js} +16 -16
- package/dist/{boot-reembed-r6shx5qx.js → boot-reembed-g5ckg9yb.js} +6 -6
- package/dist/{boot-reembed-zfxb937k.js → boot-reembed-se8zmdcp.js} +5 -5
- package/dist/{boot-scrub-logs-k5y0se6r.js → boot-scrub-logs-wfxqan61.js} +3 -3
- package/dist/{seed-pricing-vqxa06qf.js → boot-seeds-s3q01xj3.js} +10 -10
- package/dist/{claude-adapter-5yc7hxwv.js → claude-adapter-tv2x4f36.js} +7 -7
- package/dist/{claude-managed-adapter-ea2aga6w.js → claude-managed-adapter-41b2s7fd.js} +2 -2
- package/dist/{claude-sdk-session-j4ywn3xf.js → claude-sdk-session-t442qz6f.js} +8 -8
- package/dist/{cli-e781c6f9.js → cli-0xjkj1j7.js} +1 -0
- package/dist/{cli-58rgvkt4.js → cli-1hkrch3k.js} +2 -2
- package/dist/{cli-yscm6cv8.js → cli-20cj37vt.js} +1866 -9
- package/dist/{cli-h0wdadsx.js → cli-4198qc9v.js} +7 -3
- package/dist/{cli-awwphhcs.js → cli-47m6dkd3.js} +362 -126
- package/dist/{cli-wb2zvbfg.js → cli-53sz8gkz.js} +1 -1
- package/dist/{cli-005pze6s.js → cli-5d10vd2m.js} +1 -1
- package/dist/{cli-v53rbqp3.js → cli-65hjmev5.js} +57 -17
- package/dist/{cli-scwq51gn.js → cli-68w09sjw.js} +7 -1
- package/dist/{cli-s98skd5r.js → cli-7gtvvpbh.js} +4 -4
- package/dist/{cli-y3nxwx0t.js → cli-7s3syk22.js} +18 -11
- package/dist/{cli-74h6f2bp.js → cli-8qmme6vd.js} +2 -2
- package/dist/{cli-wsed24mk.js → cli-987hg0aa.js} +2 -2
- package/dist/{cli-9n76jszt.js → cli-9httdpyq.js} +1 -1
- package/dist/{cli-f3va018d.js → cli-aky8tctm.js} +26 -93
- package/dist/{cli-sgyqyyxe.js → cli-c07r9a2m.js} +2 -1
- package/dist/{cli-c41wjx0r.js → cli-fgqxwrpv.js} +291 -12
- package/dist/{cli-01vfmq8c.js → cli-ftfvggzx.js} +607 -164
- package/dist/{cli-ytxs7mn1.js → cli-g8djp6qe.js} +17 -0
- package/dist/{cli-avkd6mqv.js → cli-h967nb6r.js} +551 -0
- package/dist/{cli-r9ee9c4w.js → cli-j55n64b6.js} +23 -22
- package/dist/{cli-9p33cz9h.js → cli-j57qkrpq.js} +86 -28
- package/dist/{cli-tjmghmm5.js → cli-q67y4wzm.js} +6 -3
- package/dist/{cli-n6zq3kbd.js → cli-rj19hc34.js} +1 -1
- package/dist/{cli-jytrw2na.js → cli-rjehvrts.js} +4 -4
- package/dist/{cli-tpv97m71.js → cli-rqz8qbw7.js} +245 -75
- package/dist/{cli-p37sg0a9.js → cli-s8eet254.js} +1 -1
- package/dist/cli-t1ze64h3.js +811 -0
- package/dist/{cli-6jjzxv3b.js → cli-ws6rqycm.js} +3 -2
- package/dist/{cli-xf5b7y1f.js → cli-wscdvcqz.js} +13 -5
- package/dist/{cli-5j7bm4tb.js → cli-x24pshtq.js} +5 -5
- package/dist/{cli-nbp6m6gp.js → cli-xberxa1r.js} +51 -26
- package/dist/{cli-vx9p3qdt.js → cli-xhaeg2nc.js} +1 -1
- package/dist/cli.js +29 -15
- package/dist/{codex-adapter-gns3s6c3.js → codex-adapter-cnm8wk11.js} +5 -5
- package/dist/{codex-session-runner-gqnxys5w.js → codex-session-runner-gfg547zj.js} +5 -5
- package/dist/{commands-hxy2y2sp.js → commands-e3bn0p75.js} +3 -3
- package/dist/{db-w8ghhsgf.js → db-03v9kzr2.js} +17 -3
- package/dist/{dispatcher-cp1rknjz.js → dispatcher-nrmg8yht.js} +14 -14
- package/dist/{dsh-adapter-1dwg97zv.js → dsh-adapter-k03nfqa6.js} +2 -2
- package/dist/{handlers-egfhr351.js → handlers-aqcedbyb.js} +17 -17
- package/dist/{hook-x4kftwzt.js → hook-7vkskkre.js} +19 -11
- package/dist/{hook-fbxjqfjz.js → hook-ybvmrmhq.js} +4 -4
- package/dist/{http-c7jfx990.js → http-2eqa8t24.js} +432 -195
- package/dist/{index-4k9hct21.js → index-1yks3qcr.js} +14 -14
- package/dist/{index-jtvpgb8f.js → index-a3vn96n8.js} +30 -27
- package/dist/{index-dc2ek6bw.js → index-c6zsv1bd.js} +5 -5
- package/dist/{index-yy07ef2s.js → index-chgdkq36.js} +14 -14
- package/dist/{index-r6bty6tb.js → index-x71bvq0p.js} +15 -15
- package/dist/{keepalive-f7ekefyc.js → keepalive-vtkf5n99.js} +5 -5
- package/dist/{lead-h053syts.js → lead-h3sp357x.js} +26 -26
- package/dist/{maintenance-a3w6zs54.js → maintenance-jzeqtk3q.js} +6 -6
- package/dist/{oauth-refresh-sweep-vra1dhkd.js → oauth-refresh-sweep-qp3dzmdp.js} +4 -4
- package/dist/{onboard-mfgzeqxs.js → onboard-tmsp0qbz.js} +278 -81
- package/dist/{opencode-adapter-z64xjzec.js → opencode-adapter-x6x2da1z.js} +3 -3
- package/dist/{otel-impl-2ez6xk57.js → otel-impl-9mz73q65.js} +416 -301
- package/dist/{pi-mono-adapter-2b7mw16r.js → pi-mono-adapter-m6dvv0dz.js} +2 -2
- package/dist/{pricing-refresh-6sw65tck.js → pricing-refresh-v1cbr9te.js} +5 -5
- package/dist/{rbac-roles-nm6924sy.js → rbac-roles-c9wqz83x.js} +4 -4
- package/dist/{render-v2-f026j6c4.js → render-v2-gryrh9h8.js} +4 -4
- package/dist/{setup-w606fr1q.js → setup-q9720bt6.js} +2 -2
- package/dist/{virtual-modules-8qheft18.js → virtual-modules-3htpgn8x.js} +1 -1
- package/dist/{work-objects-ezmggdne.js → work-objects-b76x7deb.js} +17 -17
- package/dist/{worker-1mbyv29k.js → worker-6vrxbv41.js} +26 -26
- package/openapi.json +1626 -629
- package/package.json +2 -1
- package/src/apps/catalog.generated.json +229 -0
- package/src/apps/page-validator.ts +71 -16
- package/src/apps/row-store.ts +66 -11
- package/src/apps/sync.ts +59 -17
- package/src/artifact-sdk/browser-sdk.ts +436 -2
- package/src/be/approval-sweeps.ts +109 -0
- package/src/be/boot-seeds.ts +40 -0
- package/src/be/chunking.ts +1 -1
- package/src/be/db/agents.ts +20 -0
- package/src/be/db/approvals.ts +78 -0
- package/src/be/db/tasks/read.ts +197 -39
- package/src/be/db/tasks/write.ts +41 -9
- package/src/be/db-client.ts +107 -48
- package/src/be/db.ts +219 -76
- package/src/be/events.ts +33 -1
- package/src/be/memory/graph-expansion.ts +10 -3
- package/src/be/memory/providers/sqlite-store.ts +55 -13
- package/src/be/memory/raters/retrieval.ts +5 -2
- package/src/be/memory/reranker.ts +26 -2
- package/src/be/memory/types.ts +2 -0
- package/src/be/migrations/166_approval_request_auto_cancellation.sql +9 -0
- package/src/be/migrations/171_memory_retrieval_relevance.sql +8 -0
- package/src/be/migrations/175_workflow_runs_list_index.sql +11 -0
- package/src/be/migrations/177_events_event_agent_created_index.sql +11 -0
- package/src/be/models-catalog.ts +2 -0
- package/src/be/modelsdev-cache.json +1857 -0
- package/src/be/modelsdev-cache.ts +14 -1
- package/src/be/pricing-normalize.ts +2 -0
- package/src/be/scripts/typecheck.ts +1 -0
- package/src/be/seed-pricing.ts +3 -1
- package/src/be/seed-skills/bundled-files.generated.json +1 -1
- package/src/be/steering.ts +53 -3
- package/src/be/swarm-config-guard.ts +3 -0
- package/src/be/task-citations.ts +29 -0
- package/src/cli.tsx +14 -1
- package/src/commands/onboard/compose-generator.ts +8 -3
- package/src/commands/onboard/container-engine.ts +220 -0
- package/src/commands/onboard/manifest.ts +1 -0
- package/src/commands/onboard/steps/health-check.tsx +4 -1
- package/src/commands/onboard/steps/prereq-check.tsx +50 -54
- package/src/commands/onboard/steps/start.tsx +31 -16
- package/src/commands/onboard/types.ts +7 -2
- package/src/commands/onboard.tsx +39 -4
- package/src/commands/profile-sync.ts +79 -26
- package/src/commands/runner.ts +8 -1
- package/src/extensions/catalog.generated.json +17 -0
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/heartbeat/heartbeat.ts +263 -103
- package/src/hooks/hook.ts +21 -12
- package/src/http/agents.ts +35 -0
- package/src/http/approval-requests.ts +136 -64
- package/src/http/apps.ts +14 -3
- package/src/http/config.ts +15 -1
- package/src/http/events.ts +62 -2
- package/src/http/index.ts +6 -4
- package/src/http/memory.ts +21 -7
- package/src/http/schedules.ts +1 -1
- package/src/http/session-data.ts +9 -4
- package/src/http/sessions.ts +25 -18
- package/src/http/stats.ts +19 -7
- package/src/http/status.ts +11 -1
- package/src/http/tasks.ts +40 -8
- package/src/http/webhooks.ts +67 -46
- package/src/http/workflows.ts +15 -20
- package/src/linear/outbound.ts +37 -15
- package/src/otel-impl.ts +151 -1
- package/src/otel.ts +14 -3
- package/src/prompts/memories.ts +19 -2
- package/src/providers/claude-managed-models.ts +8 -0
- package/src/providers/modelsdev-reasoning.json +551 -0
- package/src/rbac/legacy-policy.ts +16 -0
- package/src/rbac/permissions.ts +4 -0
- package/src/scheduler/schedule-task.ts +3 -0
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/swarm-sdk.ts +9 -0
- package/src/scripts-runtime/types/stdlib.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-extension.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
- package/src/server.ts +12 -7
- package/src/slack/app.ts +35 -4
- package/src/slack/connection-state.ts +17 -0
- package/src/tasks/context-key.ts +1 -0
- package/src/tasks/worker-follow-up.ts +6 -2
- package/src/tests/agent-task-activity.test.ts +74 -0
- package/src/tests/agents-list-model-display.test.ts +6 -1
- package/src/tests/approval-auto-cancellation-migration.test.ts +104 -0
- package/src/tests/approval-requests.test.ts +395 -0
- package/src/tests/approval-sweeps-config.test.ts +47 -0
- package/src/tests/approval-sweeps.test.ts +508 -0
- package/src/tests/apps-kibo-blocks.test.ts +77 -0
- package/src/tests/apps-spike.test.ts +56 -1
- package/src/tests/apps-sync-engine.test.ts +20 -9
- package/src/tests/boot-seeds.test.ts +170 -0
- package/src/tests/cancel-approval-request-tool.test.ts +115 -0
- package/src/tests/claude-managed-adapter.test.ts +6 -0
- package/src/tests/config-key-filter.test.ts +80 -0
- package/src/tests/context-window.test.ts +1 -0
- package/src/tests/db-client-busy-retry.test.ts +96 -0
- package/src/tests/db-client.test.ts +60 -1
- package/src/tests/db-task-read-contract.test.ts +10 -0
- package/src/tests/db-task-write-contract.test.ts +9 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/events-http.test.ts +103 -0
- package/src/tests/extensions-catalog.test.ts +22 -17
- package/src/tests/extensions-pre-task.test.ts +107 -0
- package/src/tests/fixtures/kibo-blocks-definition.json.txt +105 -0
- package/src/tests/follow-up-config-inheritance.test.ts +260 -0
- package/src/tests/heartbeat-orphan-resume.test.ts +84 -0
- package/src/tests/heartbeat-reboot-live.test.ts +95 -0
- package/src/tests/heartbeat-stall-cas.test.ts +80 -0
- package/src/tests/heartbeat.test.ts +99 -3
- package/src/tests/hook-mcp-config.test.ts +29 -0
- package/src/tests/http-api-integration.test.ts +16 -2
- package/src/tests/kv-storage.test.ts +62 -0
- package/src/tests/linear-outbound-sync.test.ts +120 -5
- package/src/tests/list-endpoint-slimming.test.ts +91 -0
- package/src/tests/memory-graph-organic-route.test.ts +155 -0
- package/src/tests/memory-http-recall-gating.test.ts +14 -4
- package/src/tests/memory-hybrid.test.ts +161 -1
- package/src/tests/memory-prompt-recall-crowdout.test.ts +297 -0
- package/src/tests/memory.test.ts +22 -0
- package/src/tests/onboard-container-engine.test.ts +240 -0
- package/src/tests/otel-event-loop-and-logs.test.ts +99 -0
- package/src/tests/pricing-routes.test.ts +14 -0
- package/src/tests/profile-sync-warning.test.ts +8 -4
- package/src/tests/promote-draft-task-route.test.ts +19 -0
- package/src/tests/provider-registration.test.ts +296 -42
- package/src/tests/rbac-engine.test.ts +30 -0
- package/src/tests/reasoning-effort.test.ts +8 -0
- package/src/tests/script-connections.test.ts +7 -0
- package/src/tests/sdk-allowlist.test.ts +39 -0
- package/src/tests/session-costs-model-key-normalize.test.ts +1 -0
- package/src/tests/sessions-detail-batch.test.ts +250 -0
- package/src/tests/sessions.test.ts +118 -0
- package/src/tests/slack-config.test.ts +22 -0
- package/src/tests/sonnet-5-5-registry.test.ts +44 -0
- package/src/tests/status.test.ts +36 -1
- package/src/tests/swarm-diff.test.ts +316 -10
- package/src/tests/task-completion-idempotency.test.ts +2 -1
- package/src/tests/tasks-requested-by-filter.test.ts +3 -1
- package/src/tests/tool-annotations.test.ts +1 -1
- package/src/tests/ui-list-slim-projections.test.ts +158 -0
- package/src/tests/webhooks-task-blocked.test.ts +127 -0
- package/src/tests/workflow-approval-recovery.test.ts +203 -0
- package/src/tests/workflow-hitl-routing.test.ts +22 -1
- package/src/tests/workflow-hitl-slack-card.test.ts +52 -0
- package/src/tests/workflow-http-v2.test.ts +99 -8
- package/src/tests/workflow-retry-validation.test.ts +56 -0
- package/src/tests/workflow-tla-races.test.ts +389 -0
- package/src/tests/workflow-validation-port-routing.test.ts +113 -1
- package/src/tools/cancel-approval-request.ts +57 -0
- package/src/tools/memory-search.ts +1 -0
- package/src/tools/request-human-input.ts +4 -2
- package/src/tools/send-task.ts +4 -0
- package/src/tools/templates.ts +19 -0
- package/src/tools/tool-config.ts +2 -1
- package/src/tools/workflows/list-workflow-runs.ts +1 -0
- package/src/types.ts +38 -0
- package/src/utils/context-window.ts +1 -0
- package/src/workflows/approval-cancel.ts +152 -0
- package/src/workflows/approval-notifications.ts +84 -0
- package/src/workflows/checkpoint.ts +10 -5
- package/src/workflows/definition.ts +21 -0
- package/src/workflows/engine.ts +152 -21
- package/src/workflows/executors/human-in-the-loop.ts +1 -1
- package/src/workflows/recovery.ts +100 -45
- package/src/workflows/resume.ts +49 -18
- package/src/workflows/retry-poller.ts +71 -21
- package/templates/extensions/README.md +1 -0
- package/templates/extensions/github-sender-allowlist/README.md +18 -0
- package/templates/extensions/github-sender-allowlist/hooks.ts +55 -0
- package/templates/extensions/github-sender-allowlist/manifest.json +8 -0
- package/templates/skills/apps/content.md +20 -1
- package/templates/skills/code-quality/content.md +26 -1
- package/templates/skills/pages/content.md +16 -4
- package/templates/skills/pages/files/examples/multiplayer-board.html +3 -12
- package/dist/cli-2daksqps.js +0 -378
- package/dist/rbac-roles-3gxmnb20.js +0 -37
package/src/otel-impl.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { monitorEventLoopDelay } from "node:perf_hooks";
|
|
2
|
+
import { format } from "node:util";
|
|
1
3
|
import {
|
|
4
|
+
type BatchObservableResult,
|
|
2
5
|
type Counter,
|
|
3
6
|
context,
|
|
4
7
|
type Gauge,
|
|
5
8
|
type Histogram,
|
|
9
|
+
type Meter,
|
|
6
10
|
metrics,
|
|
7
11
|
propagation,
|
|
8
12
|
ROOT_CONTEXT,
|
|
@@ -12,6 +16,7 @@ import {
|
|
|
12
16
|
type Tracer,
|
|
13
17
|
trace,
|
|
14
18
|
} from "@opentelemetry/api";
|
|
19
|
+
import { logs, SeverityNumber } from "@opentelemetry/api-logs";
|
|
15
20
|
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
|
16
21
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
17
22
|
import {
|
|
@@ -149,7 +154,12 @@ export function resolveServiceName(serviceRole: string): string {
|
|
|
149
154
|
return serviceRole === "api" ? `${baseServiceName}-api` : baseServiceName;
|
|
150
155
|
}
|
|
151
156
|
|
|
152
|
-
export
|
|
157
|
+
export interface BootOptions {
|
|
158
|
+
/** Mirror console output into OTel log records (API role only). */
|
|
159
|
+
exportConsoleLogs?: boolean;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function boot(serviceRole: string, options: BootOptions = {}): Promise<void> {
|
|
153
163
|
if (sdk) return;
|
|
154
164
|
|
|
155
165
|
const configuredResourceAttributes = parseResourceAttributes();
|
|
@@ -191,6 +201,14 @@ export async function boot(serviceRole: string): Promise<void> {
|
|
|
191
201
|
|
|
192
202
|
sdk.start();
|
|
193
203
|
|
|
204
|
+
if (serviceRole === "api") {
|
|
205
|
+
startEventLoopDelayMetrics(metrics.getMeter(METER_NAME));
|
|
206
|
+
// NodeSDK already registers a global LoggerProvider exporting over OTLP
|
|
207
|
+
// to the same endpoint and resource as traces (OTEL_LOGS_EXPORTER
|
|
208
|
+
// defaults to otlp); nothing feeds it until the bridge is installed.
|
|
209
|
+
if (options.exportConsoleLogs) installConsoleLogBridge();
|
|
210
|
+
}
|
|
211
|
+
|
|
194
212
|
const shutdown = async () => {
|
|
195
213
|
try {
|
|
196
214
|
await sdk?.shutdown();
|
|
@@ -204,8 +222,140 @@ export async function boot(serviceRole: string): Promise<void> {
|
|
|
204
222
|
}
|
|
205
223
|
|
|
206
224
|
export async function shutdown(): Promise<void> {
|
|
225
|
+
// SDK first: its final flush still reads the event-loop gauges and drains
|
|
226
|
+
// bridged log records.
|
|
207
227
|
await sdk?.shutdown();
|
|
208
228
|
sdk = undefined;
|
|
229
|
+
stopEventLoopDelayMetrics();
|
|
230
|
+
uninstallConsoleLogBridge();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
let stopEventLoopDelay: (() => void) | undefined;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Event-loop delay from `perf_hooks.monitorEventLoopDelay`, exported as the
|
|
237
|
+
* semconv `nodejs.eventloop.delay.*` gauges (seconds). Each collection reads
|
|
238
|
+
* the histogram and resets it, so `max` is the worst stall since the last
|
|
239
|
+
* export. Server spans only start once the loop frees, so a stall never shows
|
|
240
|
+
* in span durations: a request queued behind a 3s synchronous query still
|
|
241
|
+
* reports a 14ms span. This metric is what sees the stall.
|
|
242
|
+
*/
|
|
243
|
+
export function startEventLoopDelayMetrics(meter: Meter): void {
|
|
244
|
+
if (stopEventLoopDelay) return;
|
|
245
|
+
const histogram = monitorEventLoopDelay({ resolution: 10 });
|
|
246
|
+
histogram.enable();
|
|
247
|
+
const gauges = {
|
|
248
|
+
min: meter.createObservableGauge("nodejs.eventloop.delay.min", {
|
|
249
|
+
description: "Minimum event loop delay since the last export",
|
|
250
|
+
unit: "s",
|
|
251
|
+
}),
|
|
252
|
+
max: meter.createObservableGauge("nodejs.eventloop.delay.max", {
|
|
253
|
+
description: "Maximum event loop delay since the last export: the longest stall",
|
|
254
|
+
unit: "s",
|
|
255
|
+
}),
|
|
256
|
+
mean: meter.createObservableGauge("nodejs.eventloop.delay.mean", {
|
|
257
|
+
description: "Mean event loop delay since the last export",
|
|
258
|
+
unit: "s",
|
|
259
|
+
}),
|
|
260
|
+
p50: meter.createObservableGauge("nodejs.eventloop.delay.p50", {
|
|
261
|
+
description: "50th percentile event loop delay since the last export",
|
|
262
|
+
unit: "s",
|
|
263
|
+
}),
|
|
264
|
+
p90: meter.createObservableGauge("nodejs.eventloop.delay.p90", {
|
|
265
|
+
description: "90th percentile event loop delay since the last export",
|
|
266
|
+
unit: "s",
|
|
267
|
+
}),
|
|
268
|
+
p99: meter.createObservableGauge("nodejs.eventloop.delay.p99", {
|
|
269
|
+
description: "99th percentile event loop delay since the last export",
|
|
270
|
+
unit: "s",
|
|
271
|
+
}),
|
|
272
|
+
};
|
|
273
|
+
const seconds = (ns: number) => ns / 1e9;
|
|
274
|
+
const collect = (observer: BatchObservableResult) => {
|
|
275
|
+
// No sample yet (first interval shorter than the resolution): the
|
|
276
|
+
// histogram's min is a sentinel then, so report nothing.
|
|
277
|
+
if (histogram.count === 0) return;
|
|
278
|
+
observer.observe(gauges.min, seconds(histogram.min));
|
|
279
|
+
observer.observe(gauges.max, seconds(histogram.max));
|
|
280
|
+
observer.observe(gauges.mean, seconds(histogram.mean));
|
|
281
|
+
observer.observe(gauges.p50, seconds(histogram.percentile(50)));
|
|
282
|
+
observer.observe(gauges.p90, seconds(histogram.percentile(90)));
|
|
283
|
+
observer.observe(gauges.p99, seconds(histogram.percentile(99)));
|
|
284
|
+
histogram.reset();
|
|
285
|
+
};
|
|
286
|
+
const observables = Object.values(gauges);
|
|
287
|
+
meter.addBatchObservableCallback(collect, observables);
|
|
288
|
+
stopEventLoopDelay = () => {
|
|
289
|
+
meter.removeBatchObservableCallback(collect, observables);
|
|
290
|
+
histogram.disable();
|
|
291
|
+
stopEventLoopDelay = undefined;
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function stopEventLoopDelayMetrics(): void {
|
|
296
|
+
stopEventLoopDelay?.();
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const CONSOLE_LOG_BODY_MAX_CHARS = 16_384;
|
|
300
|
+
const CONSOLE_SEVERITY = {
|
|
301
|
+
debug: { number: SeverityNumber.DEBUG, text: "DEBUG" },
|
|
302
|
+
log: { number: SeverityNumber.INFO, text: "INFO" },
|
|
303
|
+
info: { number: SeverityNumber.INFO, text: "INFO" },
|
|
304
|
+
warn: { number: SeverityNumber.WARN, text: "WARN" },
|
|
305
|
+
error: { number: SeverityNumber.ERROR, text: "ERROR" },
|
|
306
|
+
} as const;
|
|
307
|
+
type ConsoleMethod = keyof typeof CONSOLE_SEVERITY;
|
|
308
|
+
|
|
309
|
+
let restoreConsole: (() => void) | undefined;
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Mirror console output into OTel log records (opt-in: OTEL_EXPORT_API_LOGS).
|
|
313
|
+
* stdout/stderr stay the primary sink; each line is also emitted to the
|
|
314
|
+
* global LoggerProvider, scrubbed at this egress point and correlated with
|
|
315
|
+
* the active span.
|
|
316
|
+
*/
|
|
317
|
+
export function installConsoleLogBridge(): void {
|
|
318
|
+
if (restoreConsole) return;
|
|
319
|
+
const logger = logs.getLogger(METER_NAME);
|
|
320
|
+
const originals = new Map<ConsoleMethod, (...args: unknown[]) => void>();
|
|
321
|
+
let emitting = false;
|
|
322
|
+
for (const method of Object.keys(CONSOLE_SEVERITY) as ConsoleMethod[]) {
|
|
323
|
+
const original = console[method].bind(console);
|
|
324
|
+
originals.set(method, console[method]);
|
|
325
|
+
console[method] = (...args: unknown[]) => {
|
|
326
|
+
original(...args);
|
|
327
|
+
// An exporter or scrubber that logs must not recurse into itself.
|
|
328
|
+
if (emitting) return;
|
|
329
|
+
emitting = true;
|
|
330
|
+
try {
|
|
331
|
+
// Scrub before truncating so a cut can never split a secret into an
|
|
332
|
+
// unrecognizable fragment.
|
|
333
|
+
const text = scrubSecrets(format(...args));
|
|
334
|
+
const body =
|
|
335
|
+
text.length > CONSOLE_LOG_BODY_MAX_CHARS
|
|
336
|
+
? `${text.slice(0, CONSOLE_LOG_BODY_MAX_CHARS)}…`
|
|
337
|
+
: text;
|
|
338
|
+
logger.emit({
|
|
339
|
+
severityNumber: CONSOLE_SEVERITY[method].number,
|
|
340
|
+
severityText: CONSOLE_SEVERITY[method].text,
|
|
341
|
+
body,
|
|
342
|
+
attributes: { "log.source": "console" },
|
|
343
|
+
});
|
|
344
|
+
} catch {
|
|
345
|
+
// Log export is best-effort; never break the caller's console call.
|
|
346
|
+
} finally {
|
|
347
|
+
emitting = false;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
restoreConsole = () => {
|
|
352
|
+
for (const [method, original] of originals) console[method] = original;
|
|
353
|
+
restoreConsole = undefined;
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export function uninstallConsoleLogBridge(): void {
|
|
358
|
+
restoreConsole?.();
|
|
209
359
|
}
|
|
210
360
|
|
|
211
361
|
export async function withSpan<T>(
|
package/src/otel.ts
CHANGED
|
@@ -94,18 +94,29 @@ export function isOtelEnabled(): boolean {
|
|
|
94
94
|
return otelConfigured();
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
const v = (process.env
|
|
97
|
+
function envFlagEnabled(name: string): boolean {
|
|
98
|
+
const v = (process.env[name] ?? "").trim().toLowerCase();
|
|
99
99
|
return v === "1" || v === "true" || v === "yes" || v === "on";
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
export function isPollTracingEnabled(): boolean {
|
|
103
|
+
return envFlagEnabled("OTEL_TRACE_POLL");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Mirror the API's console output to the OTLP collector as log records. Off by default. */
|
|
107
|
+
export function isApiLogExportEnabled(): boolean {
|
|
108
|
+
return envFlagEnabled("OTEL_EXPORT_API_LOGS");
|
|
109
|
+
}
|
|
110
|
+
|
|
102
111
|
export async function initOtel(serviceRole = process.env.AGENT_ROLE || "api"): Promise<void> {
|
|
103
112
|
if (!otelConfigured() || initialized) return;
|
|
104
113
|
initialized = true;
|
|
105
114
|
|
|
106
115
|
try {
|
|
107
116
|
const impl = await import("./otel-impl");
|
|
108
|
-
await impl.boot(serviceRole
|
|
117
|
+
await impl.boot(serviceRole, {
|
|
118
|
+
exportConsoleLogs: serviceRole === "api" && isApiLogExportEnabled(),
|
|
119
|
+
});
|
|
109
120
|
realWithSpan = impl.withSpan;
|
|
110
121
|
realStartSpan = impl.startSpan;
|
|
111
122
|
realWithRemoteContext = impl.withRemoteContext;
|
package/src/prompts/memories.ts
CHANGED
|
@@ -18,9 +18,26 @@ export type RelevantMemory = {
|
|
|
18
18
|
name: string;
|
|
19
19
|
content: string;
|
|
20
20
|
similarity: number;
|
|
21
|
+
rawSimilarity?: number;
|
|
21
22
|
};
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Minimum pre-boost relevance for a memory to be injected into a task prompt.
|
|
26
|
+
*
|
|
27
|
+
* Compared against `rawSimilarity`, the [0,1] match score every retrieval arm
|
|
28
|
+
* emits before rerank (vec cosine, hybrid fused cosine, graph-derived), never
|
|
29
|
+
* against the composite `similarity`: the reranker's access, source-quality
|
|
30
|
+
* and usefulness multipliers can lift a score up to 4.5x, so a composite
|
|
31
|
+
* threshold admits unrelated rows. 0.55 sits between an unrelated query's best
|
|
32
|
+
* cosine (~0.33 on the production embedding model) and an exact-name hybrid
|
|
33
|
+
* hit (~0.65 fused).
|
|
34
|
+
*/
|
|
35
|
+
export const SIMILARITY_THRESHOLD = 0.55;
|
|
36
|
+
|
|
37
|
+
/** The score the injection threshold applies to. Older servers omit `rawSimilarity`. */
|
|
38
|
+
export function memoryRelevance(memory: { similarity: number; rawSimilarity?: number }): number {
|
|
39
|
+
return memory.rawSimilarity ?? memory.similarity;
|
|
40
|
+
}
|
|
24
41
|
|
|
25
42
|
const RATE_TOOL_HINT = `
|
|
26
43
|
|
|
@@ -35,7 +52,7 @@ This trains the swarm to surface better memories next time. Use sparingly:
|
|
|
35
52
|
* append entirely (matching pre-step-5 behaviour).
|
|
36
53
|
*/
|
|
37
54
|
export function renderMemoriesPrompt(memories: RelevantMemory[]): string | null {
|
|
38
|
-
const useful = memories.filter((m) => m
|
|
55
|
+
const useful = memories.filter((m) => memoryRelevance(m) > SIMILARITY_THRESHOLD);
|
|
39
56
|
if (useful.length === 0) return null;
|
|
40
57
|
|
|
41
58
|
const memoryContext = useful
|
|
@@ -31,6 +31,7 @@ export const CLAUDE_MANAGED_MODELS = [
|
|
|
31
31
|
"claude-opus-5",
|
|
32
32
|
"claude-fable-5",
|
|
33
33
|
"claude-mythos-5",
|
|
34
|
+
"claude-sonnet-5-5",
|
|
34
35
|
"claude-sonnet-5",
|
|
35
36
|
"claude-sonnet-4-6",
|
|
36
37
|
"claude-opus-4-8",
|
|
@@ -72,6 +73,7 @@ export interface ClaudeManagedModelPricing extends ClaudeManagedTokenPricing {
|
|
|
72
73
|
* - claude-mythos-5: $10 / $50 / $1.00 / $12.50 (limited availability, verified 2026-06-10)
|
|
73
74
|
* - claude-opus-5-5: $4 / $20 / $0.20 / $5.00 (verified 2026-09-22)
|
|
74
75
|
* - claude-opus-5: $5 / $25 / $0.50 / $6.25 (verified 2026-07-25)
|
|
76
|
+
* - claude-sonnet-5-5: $2 / $10 / $0.20 / $2.50 (verified 2026-09-28)
|
|
75
77
|
* - claude-sonnet-5: $2 / $10 / $0.20 / $2.50 (standard rate, verified 2026-08-29)
|
|
76
78
|
* - claude-sonnet-4-6: $3 / $15 / $0.30 / $3.75 (in / out / cache-read / cache-write)
|
|
77
79
|
* - claude-opus-4-8: $5 / $25 / $0.50 / $6.25 (verified 2026-05-28)
|
|
@@ -116,6 +118,12 @@ export const CLAUDE_MANAGED_MODEL_PRICING: Record<ClaudeManagedModel, ClaudeMana
|
|
|
116
118
|
cacheReadPerMillion: 1.0,
|
|
117
119
|
cacheWritePerMillion: 12.5,
|
|
118
120
|
},
|
|
121
|
+
"claude-sonnet-5-5": {
|
|
122
|
+
inputPerMillion: 2.0,
|
|
123
|
+
outputPerMillion: 10.0,
|
|
124
|
+
cacheReadPerMillion: 0.2,
|
|
125
|
+
cacheWritePerMillion: 2.5,
|
|
126
|
+
},
|
|
119
127
|
"claude-sonnet-5": {
|
|
120
128
|
inputPerMillion: 2.0,
|
|
121
129
|
outputPerMillion: 10.0,
|