@rivus/agent 0.3.1 → 0.4.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/README.md +2 -2
- package/dist/acp.d.ts +98 -0
- package/dist/acp.js +436 -0
- package/dist/agent-loop.d.ts +420 -0
- package/dist/agent-loop.js +118 -0
- package/dist/agent-memory.d.ts +98 -0
- package/dist/cli.js +6 -2
- package/dist/index.d.ts +4 -418
- package/dist/index.js +61 -147
- package/dist/rivus-daemon-cli.js +11 -7
- package/dist/rivus-plugin-testkit.d.ts +3 -98
- package/examples/a-share-briefing-analysis.mjs +93 -0
- package/examples/a-share-briefing-renderer.mjs +257 -0
- package/examples/a-share-index-evidence.mjs +99 -0
- package/examples/a-share-market-briefing.mjs +83 -0
- package/examples/a-share-market-date.mjs +10 -0
- package/examples/a-share-overseas-evidence.mjs +86 -0
- package/examples/a-share-policy-evidence.mjs +145 -0
- package/examples/a-share-provider-response.mjs +21 -0
- package/examples/a-share-sector-evidence.mjs +70 -0
- package/examples/acp-stdio-proxy.mjs +55 -0
- package/examples/current-weather.mjs +6 -32
- package/examples/https-response-reader.mjs +36 -0
- package/examples/rivus-agents.plugin.mjs +55 -3
- package/examples/rivus.config.json +30 -1
- package/package.json +11 -2
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { a as createAgentLoopSkillExecutionStart, c as createAgentLoopToolExecutionEnd, d as createAsyncIterableAgentLoop, f as createEventAgentLoop, i as createAgentLoopSkillExecutionEnd, l as createAgentLoopToolExecutionStart, m as createTextAgentLoopFromCallback, n as createAgentLoopModelExecutionEnd, o as createAgentLoopTextDelta, p as createTextAgentLoop, r as createAgentLoopModelExecutionStart, s as createAgentLoopThinkingDelta, t as createAgentLoopFromCallback, u as createAgentLoopToolExecutionUpdate } from "./agent-loop.js";
|
|
1
2
|
import { a as RIVUS_MEMORY_TOOL_ID, c as createMemoryNamespace, d as InvalidRivusPlugin, f as RIVUS_PLUGIN_API_VERSION, i as MEMORY_SCOPES, l as createRivusMemoryToolContract, m as requiresToolApproval, n as resolveRivusAgentDefinition, o as RIVUS_MEMORY_TOOL_PLUGIN_ID, p as RivusToolInputRejected, s as RIVUS_MEMORY_TOOL_VERSION, t as createRivusPluginCatalog, u as restrictMemoryScopesForAudience } from "./rivus-plugin-registry.js";
|
|
2
3
|
import { A as loadRivusDeployment, D as resolveFeishuEndpointCredentials, E as FeishuEndpointCredentialError, S as loadNodeRivusPluginModule, T as loadRivusDeploymentManifest, _ as OpenClawEnvImportError, a as RivusDeploymentDaemonLifecycleError, b as RivusDaemonConfigError, c as InvalidRivusEndpointBinding, d as AgentRuntimeDisposed, f as createAgentRuntimePool, g as createRivusDaemonShutdownController, h as createStableId, i as RivusDeploymentAutomationReadinessError, j as validateRivusDeploymentManifest, k as RivusPluginLoadError, l as createRivusAgentHost, m as createAgentInstanceRegistry, n as createRivusDeploymentCliProcess, o as RivusDeploymentReadinessError, p as AgentInstanceConflict, r as createConfiguredRivusDeploymentDaemon, s as createRivusDeploymentDaemon, t as runRivusDaemonCli, u as AgentInstanceBusy, v as createRivusEnvFromOpenClawConfig, w as RivusDeploymentManifestError, x as loadRivusDaemonConfig, y as formatRivusEnvFile } from "./rivus-daemon-cli.js";
|
|
3
4
|
import { n as assertRivusPluginConforms, r as createFakeRivusPlugin, t as RivusPluginConformanceError } from "./rivus-plugin-testkit.js";
|
|
4
|
-
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { Cause, Deferred, Effect, Exit, Fiber, Option, Stream } from "effect";
|
|
6
|
-
import { appendFile, lstat, mkdir, readFile, readdir, realpath, rename, stat, unlink, writeFile } from "node:fs/promises";
|
|
7
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
8
|
+
import { appendFile, lstat, mkdir, readFile, readdir, realpath, rename, stat, unlink, writeFile } from "node:fs/promises";
|
|
8
9
|
import { isDeepStrictEqual } from "node:util";
|
|
9
10
|
import { createServer } from "node:http";
|
|
10
11
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
@@ -649,122 +650,6 @@ function assertNonNegativeInteger(value, name) {
|
|
|
649
650
|
if (!Number.isSafeInteger(value) || value < 0) throw new Error(`${name} must be a non-negative integer`);
|
|
650
651
|
}
|
|
651
652
|
//#endregion
|
|
652
|
-
//#region src/application/agent/agent-loop.ts
|
|
653
|
-
function createAgentLoopTextDelta(delta) {
|
|
654
|
-
return {
|
|
655
|
-
delta,
|
|
656
|
-
type: "assistant_text_delta"
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
function normalizeAgentLoopEvent(event) {
|
|
660
|
-
return typeof event === "string" ? createAgentLoopTextDelta(event) : event;
|
|
661
|
-
}
|
|
662
|
-
function createAgentLoopThinkingDelta(delta) {
|
|
663
|
-
return {
|
|
664
|
-
delta,
|
|
665
|
-
type: "assistant_thinking_delta"
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
function createAgentLoopModelExecutionStart(options) {
|
|
669
|
-
return {
|
|
670
|
-
...options,
|
|
671
|
-
type: "model_execution_start"
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
|
-
function createAgentLoopModelExecutionEnd(options) {
|
|
675
|
-
return {
|
|
676
|
-
...options,
|
|
677
|
-
type: "model_execution_end"
|
|
678
|
-
};
|
|
679
|
-
}
|
|
680
|
-
function createAgentLoopSkillExecutionStart(options) {
|
|
681
|
-
return {
|
|
682
|
-
...options,
|
|
683
|
-
type: "skill_execution_start"
|
|
684
|
-
};
|
|
685
|
-
}
|
|
686
|
-
function createAgentLoopSkillExecutionEnd(options) {
|
|
687
|
-
return {
|
|
688
|
-
...options,
|
|
689
|
-
type: "skill_execution_end"
|
|
690
|
-
};
|
|
691
|
-
}
|
|
692
|
-
function createAgentLoopToolExecutionStart(options) {
|
|
693
|
-
return {
|
|
694
|
-
input: options.input,
|
|
695
|
-
toolCallId: options.toolCallId,
|
|
696
|
-
toolName: options.toolName,
|
|
697
|
-
type: "tool_execution_start"
|
|
698
|
-
};
|
|
699
|
-
}
|
|
700
|
-
function createAgentLoopToolExecutionUpdate(options) {
|
|
701
|
-
return {
|
|
702
|
-
input: options.input,
|
|
703
|
-
partialResult: options.partialResult,
|
|
704
|
-
toolCallId: options.toolCallId,
|
|
705
|
-
toolName: options.toolName,
|
|
706
|
-
type: "tool_execution_update"
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
function createAgentLoopToolExecutionEnd(options) {
|
|
710
|
-
return {
|
|
711
|
-
isError: options.isError,
|
|
712
|
-
result: options.result,
|
|
713
|
-
toolCallId: options.toolCallId,
|
|
714
|
-
toolName: options.toolName,
|
|
715
|
-
type: "tool_execution_end"
|
|
716
|
-
};
|
|
717
|
-
}
|
|
718
|
-
function createEventAgentLoop(options) {
|
|
719
|
-
return { run: (input) => {
|
|
720
|
-
const events = typeof options.events === "function" ? options.events(input) : options.events;
|
|
721
|
-
if (isPromiseLike(events)) return Stream.fromEffect(Effect.tryPromise({
|
|
722
|
-
try: () => events,
|
|
723
|
-
catch: (cause) => cause
|
|
724
|
-
})).pipe(Stream.flatMap((resolvedEvents) => Stream.fromIterable(resolvedEvents)), Stream.map(normalizeAgentLoopEvent));
|
|
725
|
-
return Stream.fromIterable(events).pipe(Stream.map(normalizeAgentLoopEvent));
|
|
726
|
-
} };
|
|
727
|
-
}
|
|
728
|
-
function createAsyncIterableAgentLoop(options) {
|
|
729
|
-
return { run: (input) => Stream.fromAsyncIterable(options.run(input), (error) => error).pipe(Stream.map(normalizeAgentLoopEvent)) };
|
|
730
|
-
}
|
|
731
|
-
function createAgentLoopFromCallback(run) {
|
|
732
|
-
return { run: (input) => Stream.fromEffect(Effect.try({
|
|
733
|
-
try: () => run(input),
|
|
734
|
-
catch: (cause) => cause
|
|
735
|
-
})).pipe(Stream.flatMap(streamFromAgentLoopCallbackResult)) };
|
|
736
|
-
}
|
|
737
|
-
function createTextAgentLoop(options) {
|
|
738
|
-
return { run: (input) => Stream.fromEffect(options.generate(input)).pipe(Stream.map((delta) => createAgentLoopTextDelta(delta))) };
|
|
739
|
-
}
|
|
740
|
-
function createTextAgentLoopFromCallback(generate) {
|
|
741
|
-
return createTextAgentLoop({ generate: (input) => Effect.tryPromise({
|
|
742
|
-
try: async () => generate(input),
|
|
743
|
-
catch: (cause) => cause
|
|
744
|
-
}) });
|
|
745
|
-
}
|
|
746
|
-
function isPromiseLike(value) {
|
|
747
|
-
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
748
|
-
}
|
|
749
|
-
function streamFromAgentLoopCallbackResult(result) {
|
|
750
|
-
if (Effect.isEffect(result)) return Stream.fromEffect(result).pipe(Stream.flatMap(streamFromAgentLoopCallbackOutput));
|
|
751
|
-
if (isPromiseLike(result)) return Stream.fromEffect(Effect.tryPromise({
|
|
752
|
-
try: () => Promise.resolve(result),
|
|
753
|
-
catch: (cause) => cause
|
|
754
|
-
})).pipe(Stream.flatMap(streamFromAgentLoopCallbackOutput));
|
|
755
|
-
return streamFromAgentLoopCallbackOutput(result);
|
|
756
|
-
}
|
|
757
|
-
function streamFromAgentLoopCallbackOutput(output) {
|
|
758
|
-
if (isEffectStream(output)) return output.pipe(Stream.map(normalizeAgentLoopEvent));
|
|
759
|
-
return (isAsyncIterable(output) ? Stream.fromAsyncIterable(output, (error) => error) : Stream.fromIterable(output)).pipe(Stream.map(normalizeAgentLoopEvent));
|
|
760
|
-
}
|
|
761
|
-
function isAsyncIterable(value) {
|
|
762
|
-
return Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
763
|
-
}
|
|
764
|
-
function isEffectStream(value) {
|
|
765
|
-
return typeof value === "object" && value !== null && Stream.StreamTypeId in value;
|
|
766
|
-
}
|
|
767
|
-
//#endregion
|
|
768
653
|
//#region src/infrastructure/http/json-fetch-request.ts
|
|
769
654
|
function createJsonFetchRequest(options = {}) {
|
|
770
655
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
@@ -6170,7 +6055,7 @@ function createAutomationMandateStore() {
|
|
|
6170
6055
|
//#endregion
|
|
6171
6056
|
//#region src/application/automation/daily-automation-schedule.ts
|
|
6172
6057
|
function createDailyAutomationSchedule(expression, timeZone, now = /* @__PURE__ */ new Date()) {
|
|
6173
|
-
const { hour, minute } = parseDailySchedule(expression);
|
|
6058
|
+
const { hour, minute, weekdays } = parseDailySchedule(expression);
|
|
6174
6059
|
try {
|
|
6175
6060
|
zonedParts(now, timeZone);
|
|
6176
6061
|
} catch (cause) {
|
|
@@ -6179,6 +6064,7 @@ function createDailyAutomationSchedule(expression, timeZone, now = /* @__PURE__
|
|
|
6179
6064
|
return Object.freeze({
|
|
6180
6065
|
currentOccurrence: (at) => {
|
|
6181
6066
|
const local = zonedParts(at, timeZone);
|
|
6067
|
+
if (!matchesWeekday(local, weekdays)) return void 0;
|
|
6182
6068
|
const occurrence = zonedMinuteToInstant({
|
|
6183
6069
|
day: local.day,
|
|
6184
6070
|
hour,
|
|
@@ -6190,36 +6076,49 @@ function createDailyAutomationSchedule(expression, timeZone, now = /* @__PURE__
|
|
|
6190
6076
|
},
|
|
6191
6077
|
nextOccurrence: (at) => {
|
|
6192
6078
|
const local = zonedParts(at, timeZone);
|
|
6193
|
-
const
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
}, timeZone);
|
|
6079
|
+
const localDate = Date.UTC(local.year, local.month - 1, local.day);
|
|
6080
|
+
for (let offsetDays = 0; offsetDays <= 7; offsetDays += 1) {
|
|
6081
|
+
const date = new Date(localDate + offsetDays * 864e5);
|
|
6082
|
+
const candidateParts = {
|
|
6083
|
+
day: date.getUTCDate(),
|
|
6084
|
+
hour,
|
|
6085
|
+
minute,
|
|
6086
|
+
month: date.getUTCMonth() + 1,
|
|
6087
|
+
year: date.getUTCFullYear()
|
|
6088
|
+
};
|
|
6089
|
+
if (!matchesWeekday(candidateParts, weekdays)) continue;
|
|
6090
|
+
const candidate = zonedMinuteToInstant(candidateParts, timeZone);
|
|
6091
|
+
if (candidate.getTime() > at.getTime()) return candidate;
|
|
6092
|
+
}
|
|
6093
|
+
throw new Error(`Automation schedule does not resolve within one week: ${expression}`);
|
|
6209
6094
|
}
|
|
6210
6095
|
});
|
|
6211
6096
|
}
|
|
6212
6097
|
function parseDailySchedule(schedule) {
|
|
6213
|
-
const match = /^(\d{1,2})\s+(\d{1,2})\s+\*\s+\*\s
|
|
6098
|
+
const match = /^(\d{1,2})\s+(\d{1,2})\s+\*\s+\*\s+(\*|1-5)$/.exec(schedule.trim());
|
|
6214
6099
|
if (!match) throw new Error(`unsupported Automation schedule: ${schedule}`);
|
|
6215
6100
|
const minute = Number(match[1]);
|
|
6216
6101
|
const hour = Number(match[2]);
|
|
6217
6102
|
if (!Number.isInteger(minute) || minute < 0 || minute > 59 || !Number.isInteger(hour) || hour < 0 || hour > 23) throw new Error(`invalid Automation schedule: ${schedule}`);
|
|
6218
|
-
return {
|
|
6103
|
+
return match[3] === "1-5" ? {
|
|
6104
|
+
hour,
|
|
6105
|
+
minute,
|
|
6106
|
+
weekdays: /* @__PURE__ */ new Set([
|
|
6107
|
+
1,
|
|
6108
|
+
2,
|
|
6109
|
+
3,
|
|
6110
|
+
4,
|
|
6111
|
+
5
|
|
6112
|
+
])
|
|
6113
|
+
} : {
|
|
6219
6114
|
hour,
|
|
6220
6115
|
minute
|
|
6221
6116
|
};
|
|
6222
6117
|
}
|
|
6118
|
+
function matchesWeekday(parts, weekdays) {
|
|
6119
|
+
if (!weekdays) return true;
|
|
6120
|
+
return weekdays.has(new Date(Date.UTC(parts.year, parts.month - 1, parts.day)).getUTCDay());
|
|
6121
|
+
}
|
|
6223
6122
|
function zonedParts(date, timeZone) {
|
|
6224
6123
|
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
6225
6124
|
day: "2-digit",
|
|
@@ -6311,7 +6210,7 @@ async function executeDue(options, schedule, at, claim) {
|
|
|
6311
6210
|
const occurrence = schedule.currentOccurrence(at);
|
|
6312
6211
|
if (!occurrence) return void 0;
|
|
6313
6212
|
const tick = claim(occurrence);
|
|
6314
|
-
const existing = await options.repository.get(
|
|
6213
|
+
const existing = await options.repository.get(options.automationId, occurrence);
|
|
6315
6214
|
if (existing?.status === "delivered") return existing;
|
|
6316
6215
|
let record = existing;
|
|
6317
6216
|
if (record?.status !== "generated") {
|
|
@@ -6384,15 +6283,18 @@ const systemClock = {
|
|
|
6384
6283
|
async function openJsonAutomationTickRepository(options) {
|
|
6385
6284
|
const records = /* @__PURE__ */ new Map();
|
|
6386
6285
|
const snapshot = await readSnapshot$1(options.filePath);
|
|
6387
|
-
for (const record of snapshot.records)
|
|
6286
|
+
for (const record of snapshot.records) {
|
|
6287
|
+
const recordKey = key(record.automationId, record.occurrence);
|
|
6288
|
+
records.set(recordKey, preferRecoveryRecord(records.get(recordKey), record));
|
|
6289
|
+
}
|
|
6388
6290
|
let pendingWrite = Promise.resolve();
|
|
6389
6291
|
return {
|
|
6390
|
-
get: async (
|
|
6292
|
+
get: async (automationId, occurrence) => records.get(key(automationId, occurrence)),
|
|
6391
6293
|
put: async (record) => {
|
|
6392
6294
|
const stored = Object.freeze({ ...record });
|
|
6393
6295
|
const operation = pendingWrite.then(async () => {
|
|
6394
6296
|
const next = new Map(records);
|
|
6395
|
-
next.set(key(record.
|
|
6297
|
+
next.set(key(record.automationId, record.occurrence), stored);
|
|
6396
6298
|
await writeSnapshot(options.filePath, [...next.values()]);
|
|
6397
6299
|
records.clear();
|
|
6398
6300
|
for (const [recordKey, value] of next) records.set(recordKey, value);
|
|
@@ -6407,13 +6309,13 @@ async function readSnapshot$1(filePath) {
|
|
|
6407
6309
|
const raw = await readPersistenceFile(filePath);
|
|
6408
6310
|
if (raw === void 0) return Object.freeze({
|
|
6409
6311
|
records: Object.freeze([]),
|
|
6410
|
-
version:
|
|
6312
|
+
version: 3
|
|
6411
6313
|
});
|
|
6412
6314
|
const value = JSON.parse(raw);
|
|
6413
|
-
if (!isRecord$4(value) || value.version !== 2 || !Array.isArray(value.records)) throw new Error("Automation Tick snapshot must contain version 2 records");
|
|
6315
|
+
if (!isRecord$4(value) || value.version !== 2 && value.version !== 3 || !Array.isArray(value.records)) throw new Error("Automation Tick snapshot must contain version 2 or 3 records");
|
|
6414
6316
|
return Object.freeze({
|
|
6415
6317
|
records: Object.freeze(value.records.map(readRecord)),
|
|
6416
|
-
version:
|
|
6318
|
+
version: value.version
|
|
6417
6319
|
});
|
|
6418
6320
|
}
|
|
6419
6321
|
async function writeSnapshot(filePath, records) {
|
|
@@ -6422,7 +6324,7 @@ async function writeSnapshot(filePath, records) {
|
|
|
6422
6324
|
try {
|
|
6423
6325
|
await writeFile(temporaryPath, `${JSON.stringify({
|
|
6424
6326
|
records,
|
|
6425
|
-
version:
|
|
6327
|
+
version: 3
|
|
6426
6328
|
})}\n`, {
|
|
6427
6329
|
encoding: "utf8",
|
|
6428
6330
|
flag: "wx"
|
|
@@ -6463,8 +6365,20 @@ function readRecord(value) {
|
|
|
6463
6365
|
tickId: value.tickId
|
|
6464
6366
|
});
|
|
6465
6367
|
}
|
|
6466
|
-
function key(
|
|
6467
|
-
return `${
|
|
6368
|
+
function key(automationId, occurrence) {
|
|
6369
|
+
return `${automationId}\0${occurrence}`;
|
|
6370
|
+
}
|
|
6371
|
+
function preferRecoveryRecord(current, candidate) {
|
|
6372
|
+
if (!current) return candidate;
|
|
6373
|
+
return recoveryRank(candidate.status) >= recoveryRank(current.status) ? candidate : current;
|
|
6374
|
+
}
|
|
6375
|
+
function recoveryRank(status) {
|
|
6376
|
+
switch (status) {
|
|
6377
|
+
case "delivered": return 4;
|
|
6378
|
+
case "generated": return 3;
|
|
6379
|
+
case "failed": return 2;
|
|
6380
|
+
case "running": return 1;
|
|
6381
|
+
}
|
|
6468
6382
|
}
|
|
6469
6383
|
function isStatus(value) {
|
|
6470
6384
|
return value === "running" || value === "failed" || value === "generated" || value === "delivered";
|
package/dist/rivus-daemon-cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { i as MEMORY_SCOPES, n as resolveRivusAgentDefinition, r as deepFreeze, t as createRivusPluginCatalog } from "./rivus-plugin-registry.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
5
|
import { pathToFileURL } from "node:url";
|
|
4
6
|
import { dirname, isAbsolute, join, relative, sep } from "node:path";
|
|
5
|
-
import { Effect } from "effect";
|
|
6
7
|
import { open, readFile, realpath, stat } from "node:fs/promises";
|
|
7
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
8
8
|
import { constants } from "node:fs";
|
|
9
9
|
//#region src/application/plugin/rivus-automation-runtime-definition.ts
|
|
10
10
|
function resolveRivusAutomationRuntimeDefinition(definition, requestedToolIds, requestedSkillIds) {
|
|
@@ -136,6 +136,9 @@ async function loadRivusDeployment(options) {
|
|
|
136
136
|
for (const automation of options.manifest.automations ?? []) {
|
|
137
137
|
const agent = agentStatusById.get(automation.agentId);
|
|
138
138
|
if (!agent || agent.status === "disabled" || !agent.definition) continue;
|
|
139
|
+
const deliveryEndpoint = options.manifest.endpoints.find(({ id }) => id === automation.delivery.endpointId);
|
|
140
|
+
const presentationAgent = agentStatusById.get(deliveryEndpoint.agentId);
|
|
141
|
+
if (!presentationAgent || presentationAgent.status === "disabled" || !presentationAgent.definition) continue;
|
|
139
142
|
const template = automationTemplates.get(automation.templateId);
|
|
140
143
|
if (!template) throw new Error(`automation ${automation.id} references unknown template: ${automation.templateId}`);
|
|
141
144
|
if (template.pluginId !== agent.pluginId || template.profileId !== agent.profileId) throw new Error(`automation ${automation.id} template is not owned by agent profile ${agent.profileId}`);
|
|
@@ -173,11 +176,10 @@ function validateRivusDeploymentManifest(manifest) {
|
|
|
173
176
|
for (const automation of manifest.automations ?? []) {
|
|
174
177
|
if (automationIds.has(automation.id)) throw new Error(`duplicate automation binding: ${automation.id}`);
|
|
175
178
|
automationIds.add(automation.id);
|
|
176
|
-
|
|
177
|
-
if (!agent) throw new Error(`automation ${automation.id} references unknown agent: ${automation.agentId}`);
|
|
179
|
+
if (!agentById.get(automation.agentId)) throw new Error(`automation ${automation.id} references unknown agent: ${automation.agentId}`);
|
|
178
180
|
const endpoint = manifest.endpoints.find(({ id }) => id === automation.delivery.endpointId);
|
|
179
181
|
if (!endpoint) throw new Error(`automation ${automation.id} references unknown delivery endpoint: ${automation.delivery.endpointId}`);
|
|
180
|
-
if (
|
|
182
|
+
if (automation.enabled && !endpoint.enabled) throw new Error(`automation ${automation.id} delivery endpoint must be enabled`);
|
|
181
183
|
}
|
|
182
184
|
const endpointIds = /* @__PURE__ */ new Set();
|
|
183
185
|
const sessionNamespaces = /* @__PURE__ */ new Set();
|
|
@@ -1067,13 +1069,15 @@ async function createRivusDeploymentDaemon(options) {
|
|
|
1067
1069
|
}
|
|
1068
1070
|
for (const slot of automationSlots) {
|
|
1069
1071
|
const resolvedDefinition = slot.resolvedDefinition;
|
|
1070
|
-
const
|
|
1072
|
+
const deliverySlot = slotById.get(slot.definition.delivery.endpointId);
|
|
1073
|
+
const presentationReady = deliverySlot.lifecycle === "running" && (deliverySlot.adapter?.running() ?? false);
|
|
1074
|
+
const slotDegraded = await startSlot(slot, slot.agentEnabled && resolvedDefinition !== void 0 && presentationReady, async () => {
|
|
1071
1075
|
if (!options.createAutomation) throw new RivusDeploymentDaemonLifecycleError("deployment bootstrap does not provide Automation adapters");
|
|
1072
1076
|
if (!resolvedDefinition) throw new RivusDeploymentDaemonLifecycleError(`automation definition not resolved: ${slot.definition.id}`);
|
|
1073
1077
|
return options.createAutomation({
|
|
1074
1078
|
automationId: slot.definition.id,
|
|
1075
1079
|
definition: resolvedDefinition,
|
|
1076
|
-
deliveryEndpoint:
|
|
1080
|
+
deliveryEndpoint: deliverySlot.definition,
|
|
1077
1081
|
instanceId: host.resolveAutomation(slot.definition.id).instanceId,
|
|
1078
1082
|
run: (input) => host.handleAutomation(slot.definition.id, {
|
|
1079
1083
|
invocation: {
|
|
@@ -1,100 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
declare const RIVUS_MEMORY_TOOL_ID = "memory";
|
|
4
|
-
declare const RIVUS_MEMORY_TOOL_PLUGIN_ID = "rivus-core";
|
|
5
|
-
declare const RIVUS_MEMORY_TOOL_VERSION = "1.0.0";
|
|
6
|
-
type MemoryScope = (typeof MEMORY_SCOPES)[number];
|
|
7
|
-
type MemoryState = "proposed" | "confirmed" | "superseded" | "tombstoned";
|
|
8
|
-
type MemoryInvocationAudience = "group" | "private";
|
|
9
|
-
interface AgentMemoryIdentity {
|
|
10
|
-
readonly audience: MemoryInvocationAudience;
|
|
11
|
-
readonly conversationId?: string;
|
|
12
|
-
readonly subjectId: string;
|
|
13
|
-
readonly tenantId: string;
|
|
14
|
-
}
|
|
15
|
-
interface AgentMemoryAuthority extends AgentMemoryIdentity {
|
|
16
|
-
readonly scopes: ReadonlyArray<MemoryScope>;
|
|
17
|
-
}
|
|
18
|
-
interface MemoryBinding {
|
|
19
|
-
readonly agentId: string;
|
|
20
|
-
readonly conversationId?: string;
|
|
21
|
-
readonly scope: MemoryScope;
|
|
22
|
-
readonly subjectId: string;
|
|
23
|
-
readonly tenantId: string;
|
|
24
|
-
}
|
|
25
|
-
interface MemoryRecord {
|
|
26
|
-
readonly content: string;
|
|
27
|
-
readonly conversationSafe: boolean;
|
|
28
|
-
readonly id: string;
|
|
29
|
-
readonly revision: number;
|
|
30
|
-
readonly scope: MemoryScope;
|
|
31
|
-
readonly state: MemoryState;
|
|
32
|
-
readonly tombstoneReason?: string;
|
|
33
|
-
}
|
|
34
|
-
interface AgentMemorySnapshot {
|
|
35
|
-
readonly binding: MemoryBinding;
|
|
36
|
-
readonly record: MemoryRecord;
|
|
37
|
-
}
|
|
38
|
-
declare function createMemoryNamespace(binding: MemoryBinding): string;
|
|
39
|
-
declare function restrictMemoryScopesForAudience(scopes: ReadonlyArray<MemoryScope>, audience: MemoryInvocationAudience): ReadonlyArray<MemoryScope>;
|
|
40
|
-
declare function createRivusMemoryToolContract(scopes: ReadonlyArray<MemoryScope>): Readonly<{
|
|
41
|
-
description: "Search and read Memory inside Host-bound scopes; propose or request forgetting only in writable private scopes.";
|
|
42
|
-
digest: "sha256:rivus-memory-v3";
|
|
43
|
-
id: "memory";
|
|
44
|
-
idempotency: "required";
|
|
45
|
-
inputSchema: Readonly<{
|
|
46
|
-
additionalProperties: false;
|
|
47
|
-
properties: {
|
|
48
|
-
scope?: {
|
|
49
|
-
description: string;
|
|
50
|
-
enum: ("conversation" | "agent-private" | "shared-user-profile")[];
|
|
51
|
-
type: string;
|
|
52
|
-
};
|
|
53
|
-
command: {
|
|
54
|
-
description: string;
|
|
55
|
-
enum: string[];
|
|
56
|
-
type: string;
|
|
57
|
-
};
|
|
58
|
-
id: {
|
|
59
|
-
description: string;
|
|
60
|
-
minLength: number;
|
|
61
|
-
type: string;
|
|
62
|
-
};
|
|
63
|
-
input: {
|
|
64
|
-
additionalProperties: boolean;
|
|
65
|
-
description: string;
|
|
66
|
-
properties: {
|
|
67
|
-
content: {
|
|
68
|
-
minLength: number;
|
|
69
|
-
type: string;
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
required: string[];
|
|
73
|
-
type: string;
|
|
74
|
-
};
|
|
75
|
-
query: {
|
|
76
|
-
additionalProperties: boolean;
|
|
77
|
-
description: string;
|
|
78
|
-
properties: {
|
|
79
|
-
query: {
|
|
80
|
-
type: string;
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
required: string[];
|
|
84
|
-
type: string;
|
|
85
|
-
};
|
|
86
|
-
reason: {
|
|
87
|
-
description: string;
|
|
88
|
-
type: string;
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
required: string[];
|
|
92
|
-
type: "object";
|
|
93
|
-
}>;
|
|
94
|
-
risk: "mutate";
|
|
95
|
-
version: "1.0.0";
|
|
96
|
-
}>;
|
|
97
|
-
//#endregion
|
|
1
|
+
import { c as MemoryScope, t as AgentMemoryAuthority } from "./agent-memory.js";
|
|
2
|
+
|
|
98
3
|
//#region src/domain/rivus-plugin.d.ts
|
|
99
4
|
declare const RIVUS_PLUGIN_API_VERSION = "1";
|
|
100
5
|
type RivusToolRisk = "observe" | "mutate" | "irreversible" | "host-control";
|
|
@@ -288,4 +193,4 @@ declare class RivusPluginConformanceError extends Error {
|
|
|
288
193
|
declare function assertRivusPluginConforms(input: RivusPluginConformanceInput): Promise<RivusPluginConformanceReport>;
|
|
289
194
|
declare function createFakeRivusPlugin(): RivusPlugin;
|
|
290
195
|
//#endregion
|
|
291
|
-
export { RivusToolExecutionContext as A,
|
|
196
|
+
export { RivusToolExecutionContext as A, RivusPluginCatalogSnapshot as C, RivusSkillDescriptor as D, RivusResolvedToolDescriptor as E, RivusToolInputRejected as F, RivusToolRisk as I, requiresToolApproval as L, RivusToolFactoryContext as M, RivusToolGrantSet as N, RivusSkillGrantSet as O, RivusToolIdempotency as P, RivusPluginCatalog as S, RivusPluginRegistry as T, RivusAutomationInput as _, assertRivusPluginConforms as a, RivusHostToolDescriptor as b, RIVUS_PLUGIN_API_VERSION as c, RegisteredRivusPlugin as d, RegisteredRivusSkill as f, RivusAgentProfile as g, RivusAgentDeployment as h, RivusPluginLifecycleProbe as i, RivusToolExecutor as j, RivusToolDescriptor as k, RegisteredRivusAgentProfile as l, ResolvedRivusAgentDefinition as m, RivusPluginConformanceInput as n, createFakeRivusPlugin as o, RegisteredRivusTool as p, RivusPluginConformanceReport as r, InvalidRivusPlugin as s, RivusPluginConformanceError as t, RegisteredRivusAutomation as u, RivusAutomationTemplate as v, RivusPluginManifest as w, RivusPlugin as x, RivusAutomationTickContext as y };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export function analyzeAShareBriefing({ overseasEvidence, quotes, sectorEvidence }) {
|
|
2
|
+
return Object.freeze({
|
|
3
|
+
index: Object.freeze(analyzeIndexStructure(quotes)),
|
|
4
|
+
overseas: Object.freeze(analyzeOverseasStructure(overseasEvidence)),
|
|
5
|
+
sector: analyzeSectorStructure(sectorEvidence),
|
|
6
|
+
turnover: quotes
|
|
7
|
+
.filter(({ symbol }) => symbol === "sh000001" || symbol === "sz399001")
|
|
8
|
+
.reduce((sum, quote) => sum + quote.amount, 0)
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function analyzeIndexStructure(quotes) {
|
|
13
|
+
const direction = readDirection(quotes);
|
|
14
|
+
const ranked = [...quotes].sort((left, right) => right.changePercent - left.changePercent);
|
|
15
|
+
const strongest = ranked[0];
|
|
16
|
+
const weakest = ranked.at(-1);
|
|
17
|
+
const spread = strongest.changePercent - weakest.changePercent;
|
|
18
|
+
const dispersion = spread >= 1.5 ? "结构分化较大" : spread >= 0.75 ? "存在一定分化" : "表现相对同步";
|
|
19
|
+
const average = quotes.reduce((sum, quote) => sum + quote.changePercent, 0) / quotes.length;
|
|
20
|
+
const positive = quotes.filter(({ changePercent }) => changePercent > 0).length;
|
|
21
|
+
const negative = quotes.filter(({ changePercent }) => changePercent < 0).length;
|
|
22
|
+
const strength =
|
|
23
|
+
positive === quotes.length
|
|
24
|
+
? "四个指数一致收涨,指数层面的风险偏好偏强。"
|
|
25
|
+
: negative === quotes.length
|
|
26
|
+
? "四个指数一致收跌,指数层面的风险偏好偏弱。"
|
|
27
|
+
: average >= 0.5
|
|
28
|
+
? "多数指数收涨且平均涨幅偏强,但方向并不完全一致。"
|
|
29
|
+
: average <= -0.5
|
|
30
|
+
? "多数指数承压且平均跌幅偏弱,仍需防范弱势扩散。"
|
|
31
|
+
: "指数涨跌互现,尚未形成一致的市场方向。";
|
|
32
|
+
const growth = quotes.find(({ name }) => name === "创业板指");
|
|
33
|
+
const largeCap = quotes.find(({ name }) => name === "沪深 300");
|
|
34
|
+
const styleGap = growth.changePercent - largeCap.changePercent;
|
|
35
|
+
const style =
|
|
36
|
+
styleGap >= 0.5
|
|
37
|
+
? `创业板指较沪深 300 高 ${formatPercentagePoint(styleGap)},成长风格相对占优。`
|
|
38
|
+
: styleGap <= -0.5
|
|
39
|
+
? `沪深 300 较创业板指高 ${formatPercentagePoint(-styleGap)},大盘风格相对占优。`
|
|
40
|
+
: "创业板指与沪深 300 表现接近,暂未形成清晰的成长/大盘偏向。";
|
|
41
|
+
const risk =
|
|
42
|
+
spread >= 1.5
|
|
43
|
+
? `最强与最弱指数相差 ${formatPercentagePoint(spread)},单看综合指数可能掩盖明显分化。`
|
|
44
|
+
: `最强与最弱指数相差 ${formatPercentagePoint(spread)},指数间分化暂时可控。`;
|
|
45
|
+
return { direction: `四个宽基指数 ${direction}`, dispersion, risk, strength, strongest, style, weakest };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function analyzeOverseasStructure(evidence) {
|
|
49
|
+
if (!evidence) {
|
|
50
|
+
return {
|
|
51
|
+
conclusion: "隔夜海外指数数据不可用,外部风险背景待开盘数据确认",
|
|
52
|
+
direction: undefined,
|
|
53
|
+
inference: "海外指数数据不可用,不补写外部市场判断。"
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const direction = readDirection(evidence.quotes);
|
|
57
|
+
const average = evidence.quotes.reduce((sum, quote) => sum + quote.changePercent, 0) / evidence.quotes.length;
|
|
58
|
+
const conclusion = `隔夜美股 ${direction},外部风险背景${average >= 0.3 ? "偏积极" : average <= -0.3 ? "偏谨慎" : "偏中性"}`;
|
|
59
|
+
const nasdaq = evidence.quotes.find(({ symbol }) => symbol === "usIXIC");
|
|
60
|
+
const sp500 = evidence.quotes.find(({ symbol }) => symbol === "usINX");
|
|
61
|
+
const gap = nasdaq.changePercent - sp500.changePercent;
|
|
62
|
+
const relative =
|
|
63
|
+
gap >= 0.3
|
|
64
|
+
? `纳斯达克较标普 500 高 ${formatPercentagePoint(gap)},海外科技风险偏好相对更强。`
|
|
65
|
+
: gap <= -0.3
|
|
66
|
+
? `纳斯达克较标普 500 低 ${formatPercentagePoint(-gap)},海外科技风险偏好相对更弱。`
|
|
67
|
+
: "纳斯达克与标普 500 表现接近,海外科技风格未显示明显偏离。";
|
|
68
|
+
return { conclusion, direction, inference: `${conclusion}。${relative}` };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function analyzeSectorStructure(evidence) {
|
|
72
|
+
if (!evidence) return "行业数据不可用,不补写行业主线判断。";
|
|
73
|
+
const leaders = evidence.leaders
|
|
74
|
+
.slice(0, 2)
|
|
75
|
+
.map(({ name }) => name)
|
|
76
|
+
.join("、");
|
|
77
|
+
const laggards = evidence.laggards
|
|
78
|
+
.slice(0, 2)
|
|
79
|
+
.map(({ name }) => name)
|
|
80
|
+
.join("、");
|
|
81
|
+
return `领涨端集中在${leaders},领跌端集中在${laggards};这只描述行业横截面强弱,不构成市场涨跌的驱动归因。`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function readDirection(quotes) {
|
|
85
|
+
const positive = quotes.filter(({ changePercent }) => changePercent > 0).length;
|
|
86
|
+
const negative = quotes.filter(({ changePercent }) => changePercent < 0).length;
|
|
87
|
+
const flat = quotes.length - positive - negative;
|
|
88
|
+
return `${positive} 涨 ${negative} 跌${flat > 0 ? ` ${flat} 平` : ""}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function formatPercentagePoint(value) {
|
|
92
|
+
return `${value.toFixed(2)} 个百分点`;
|
|
93
|
+
}
|