@rivus/agent 0.3.1 → 0.4.1
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 +3 -3
- 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 +63 -150
- 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;
|
|
@@ -3246,7 +3131,7 @@ function createConfiguredRivusDaemonBootstrap(options) {
|
|
|
3246
3131
|
...options.initialEvents ? { initialEvents: options.initialEvents } : {},
|
|
3247
3132
|
...options.initialRunStates ? { initialRunStates: options.initialRunStates } : {},
|
|
3248
3133
|
loop: options.loop,
|
|
3249
|
-
|
|
3134
|
+
periodicFlush,
|
|
3250
3135
|
prepareRun,
|
|
3251
3136
|
publish: (action) => publisher.publish(action),
|
|
3252
3137
|
runIds: options.runIds
|
|
@@ -3298,10 +3183,9 @@ function createConfiguredRivusDaemonBootstrap(options) {
|
|
|
3298
3183
|
};
|
|
3299
3184
|
}
|
|
3300
3185
|
function createPeriodicFlush(options, publisher) {
|
|
3301
|
-
if (options.flushIntervalMs === void 0) return;
|
|
3302
3186
|
return createFeishuPeriodicFlush({
|
|
3303
3187
|
flush: () => publisher.flush(),
|
|
3304
|
-
intervalMs: options.flushIntervalMs,
|
|
3188
|
+
intervalMs: options.flushIntervalMs ?? options.config.feishu.streamMinIntervalMs,
|
|
3305
3189
|
sleep: options.sleep
|
|
3306
3190
|
});
|
|
3307
3191
|
}
|
|
@@ -6170,7 +6054,7 @@ function createAutomationMandateStore() {
|
|
|
6170
6054
|
//#endregion
|
|
6171
6055
|
//#region src/application/automation/daily-automation-schedule.ts
|
|
6172
6056
|
function createDailyAutomationSchedule(expression, timeZone, now = /* @__PURE__ */ new Date()) {
|
|
6173
|
-
const { hour, minute } = parseDailySchedule(expression);
|
|
6057
|
+
const { hour, minute, weekdays } = parseDailySchedule(expression);
|
|
6174
6058
|
try {
|
|
6175
6059
|
zonedParts(now, timeZone);
|
|
6176
6060
|
} catch (cause) {
|
|
@@ -6179,6 +6063,7 @@ function createDailyAutomationSchedule(expression, timeZone, now = /* @__PURE__
|
|
|
6179
6063
|
return Object.freeze({
|
|
6180
6064
|
currentOccurrence: (at) => {
|
|
6181
6065
|
const local = zonedParts(at, timeZone);
|
|
6066
|
+
if (!matchesWeekday(local, weekdays)) return void 0;
|
|
6182
6067
|
const occurrence = zonedMinuteToInstant({
|
|
6183
6068
|
day: local.day,
|
|
6184
6069
|
hour,
|
|
@@ -6190,36 +6075,49 @@ function createDailyAutomationSchedule(expression, timeZone, now = /* @__PURE__
|
|
|
6190
6075
|
},
|
|
6191
6076
|
nextOccurrence: (at) => {
|
|
6192
6077
|
const local = zonedParts(at, timeZone);
|
|
6193
|
-
const
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
}, timeZone);
|
|
6078
|
+
const localDate = Date.UTC(local.year, local.month - 1, local.day);
|
|
6079
|
+
for (let offsetDays = 0; offsetDays <= 7; offsetDays += 1) {
|
|
6080
|
+
const date = new Date(localDate + offsetDays * 864e5);
|
|
6081
|
+
const candidateParts = {
|
|
6082
|
+
day: date.getUTCDate(),
|
|
6083
|
+
hour,
|
|
6084
|
+
minute,
|
|
6085
|
+
month: date.getUTCMonth() + 1,
|
|
6086
|
+
year: date.getUTCFullYear()
|
|
6087
|
+
};
|
|
6088
|
+
if (!matchesWeekday(candidateParts, weekdays)) continue;
|
|
6089
|
+
const candidate = zonedMinuteToInstant(candidateParts, timeZone);
|
|
6090
|
+
if (candidate.getTime() > at.getTime()) return candidate;
|
|
6091
|
+
}
|
|
6092
|
+
throw new Error(`Automation schedule does not resolve within one week: ${expression}`);
|
|
6209
6093
|
}
|
|
6210
6094
|
});
|
|
6211
6095
|
}
|
|
6212
6096
|
function parseDailySchedule(schedule) {
|
|
6213
|
-
const match = /^(\d{1,2})\s+(\d{1,2})\s+\*\s+\*\s
|
|
6097
|
+
const match = /^(\d{1,2})\s+(\d{1,2})\s+\*\s+\*\s+(\*|1-5)$/.exec(schedule.trim());
|
|
6214
6098
|
if (!match) throw new Error(`unsupported Automation schedule: ${schedule}`);
|
|
6215
6099
|
const minute = Number(match[1]);
|
|
6216
6100
|
const hour = Number(match[2]);
|
|
6217
6101
|
if (!Number.isInteger(minute) || minute < 0 || minute > 59 || !Number.isInteger(hour) || hour < 0 || hour > 23) throw new Error(`invalid Automation schedule: ${schedule}`);
|
|
6218
|
-
return {
|
|
6102
|
+
return match[3] === "1-5" ? {
|
|
6103
|
+
hour,
|
|
6104
|
+
minute,
|
|
6105
|
+
weekdays: /* @__PURE__ */ new Set([
|
|
6106
|
+
1,
|
|
6107
|
+
2,
|
|
6108
|
+
3,
|
|
6109
|
+
4,
|
|
6110
|
+
5
|
|
6111
|
+
])
|
|
6112
|
+
} : {
|
|
6219
6113
|
hour,
|
|
6220
6114
|
minute
|
|
6221
6115
|
};
|
|
6222
6116
|
}
|
|
6117
|
+
function matchesWeekday(parts, weekdays) {
|
|
6118
|
+
if (!weekdays) return true;
|
|
6119
|
+
return weekdays.has(new Date(Date.UTC(parts.year, parts.month - 1, parts.day)).getUTCDay());
|
|
6120
|
+
}
|
|
6223
6121
|
function zonedParts(date, timeZone) {
|
|
6224
6122
|
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
6225
6123
|
day: "2-digit",
|
|
@@ -6311,7 +6209,7 @@ async function executeDue(options, schedule, at, claim) {
|
|
|
6311
6209
|
const occurrence = schedule.currentOccurrence(at);
|
|
6312
6210
|
if (!occurrence) return void 0;
|
|
6313
6211
|
const tick = claim(occurrence);
|
|
6314
|
-
const existing = await options.repository.get(
|
|
6212
|
+
const existing = await options.repository.get(options.automationId, occurrence);
|
|
6315
6213
|
if (existing?.status === "delivered") return existing;
|
|
6316
6214
|
let record = existing;
|
|
6317
6215
|
if (record?.status !== "generated") {
|
|
@@ -6384,15 +6282,18 @@ const systemClock = {
|
|
|
6384
6282
|
async function openJsonAutomationTickRepository(options) {
|
|
6385
6283
|
const records = /* @__PURE__ */ new Map();
|
|
6386
6284
|
const snapshot = await readSnapshot$1(options.filePath);
|
|
6387
|
-
for (const record of snapshot.records)
|
|
6285
|
+
for (const record of snapshot.records) {
|
|
6286
|
+
const recordKey = key(record.automationId, record.occurrence);
|
|
6287
|
+
records.set(recordKey, preferRecoveryRecord(records.get(recordKey), record));
|
|
6288
|
+
}
|
|
6388
6289
|
let pendingWrite = Promise.resolve();
|
|
6389
6290
|
return {
|
|
6390
|
-
get: async (
|
|
6291
|
+
get: async (automationId, occurrence) => records.get(key(automationId, occurrence)),
|
|
6391
6292
|
put: async (record) => {
|
|
6392
6293
|
const stored = Object.freeze({ ...record });
|
|
6393
6294
|
const operation = pendingWrite.then(async () => {
|
|
6394
6295
|
const next = new Map(records);
|
|
6395
|
-
next.set(key(record.
|
|
6296
|
+
next.set(key(record.automationId, record.occurrence), stored);
|
|
6396
6297
|
await writeSnapshot(options.filePath, [...next.values()]);
|
|
6397
6298
|
records.clear();
|
|
6398
6299
|
for (const [recordKey, value] of next) records.set(recordKey, value);
|
|
@@ -6407,13 +6308,13 @@ async function readSnapshot$1(filePath) {
|
|
|
6407
6308
|
const raw = await readPersistenceFile(filePath);
|
|
6408
6309
|
if (raw === void 0) return Object.freeze({
|
|
6409
6310
|
records: Object.freeze([]),
|
|
6410
|
-
version:
|
|
6311
|
+
version: 3
|
|
6411
6312
|
});
|
|
6412
6313
|
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");
|
|
6314
|
+
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
6315
|
return Object.freeze({
|
|
6415
6316
|
records: Object.freeze(value.records.map(readRecord)),
|
|
6416
|
-
version:
|
|
6317
|
+
version: value.version
|
|
6417
6318
|
});
|
|
6418
6319
|
}
|
|
6419
6320
|
async function writeSnapshot(filePath, records) {
|
|
@@ -6422,7 +6323,7 @@ async function writeSnapshot(filePath, records) {
|
|
|
6422
6323
|
try {
|
|
6423
6324
|
await writeFile(temporaryPath, `${JSON.stringify({
|
|
6424
6325
|
records,
|
|
6425
|
-
version:
|
|
6326
|
+
version: 3
|
|
6426
6327
|
})}\n`, {
|
|
6427
6328
|
encoding: "utf8",
|
|
6428
6329
|
flag: "wx"
|
|
@@ -6463,8 +6364,20 @@ function readRecord(value) {
|
|
|
6463
6364
|
tickId: value.tickId
|
|
6464
6365
|
});
|
|
6465
6366
|
}
|
|
6466
|
-
function key(
|
|
6467
|
-
return `${
|
|
6367
|
+
function key(automationId, occurrence) {
|
|
6368
|
+
return `${automationId}\0${occurrence}`;
|
|
6369
|
+
}
|
|
6370
|
+
function preferRecoveryRecord(current, candidate) {
|
|
6371
|
+
if (!current) return candidate;
|
|
6372
|
+
return recoveryRank(candidate.status) >= recoveryRank(current.status) ? candidate : current;
|
|
6373
|
+
}
|
|
6374
|
+
function recoveryRank(status) {
|
|
6375
|
+
switch (status) {
|
|
6376
|
+
case "delivered": return 4;
|
|
6377
|
+
case "generated": return 3;
|
|
6378
|
+
case "failed": return 2;
|
|
6379
|
+
case "running": return 1;
|
|
6380
|
+
}
|
|
6468
6381
|
}
|
|
6469
6382
|
function isStatus(value) {
|
|
6470
6383
|
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
|
+
}
|