@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/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
- ...periodicFlush ? { periodicFlush } : {},
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 today = zonedMinuteToInstant({
6194
- day: local.day,
6195
- hour,
6196
- minute,
6197
- month: local.month,
6198
- year: local.year
6199
- }, timeZone);
6200
- if (today.getTime() > at.getTime()) return today;
6201
- const nextDate = new Date(Date.UTC(local.year, local.month - 1, local.day) + 864e5);
6202
- return zonedMinuteToInstant({
6203
- day: nextDate.getUTCDate(),
6204
- hour,
6205
- minute,
6206
- month: nextDate.getUTCMonth() + 1,
6207
- year: nextDate.getUTCFullYear()
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+\*$/.exec(schedule.trim());
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(tick.mandateId, occurrence);
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) records.set(key(record.mandateId, record.occurrence), record);
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 (mandateId, occurrence) => records.get(key(mandateId, occurrence)),
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.mandateId, record.occurrence), stored);
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: 2
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: 2
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: 2
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(mandateId, occurrence) {
6467
- return `${mandateId}\0${occurrence}`;
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";
@@ -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
- const agent = agentById.get(automation.agentId);
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 (endpoint.agentId !== agent.agentId) throw new Error(`automation ${automation.id} delivery endpoint is bound to a different agent`);
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 slotDegraded = await startSlot(slot, slot.agentEnabled && resolvedDefinition !== void 0, async () => {
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: slotById.get(slot.definition.delivery.endpointId).definition,
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
- //#region src/domain/agent-memory.d.ts
2
- declare const MEMORY_SCOPES: readonly ["conversation", "agent-private", "shared-user-profile"];
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, AgentMemorySnapshot as B, RivusPluginCatalogSnapshot as C, RivusSkillDescriptor as D, RivusResolvedToolDescriptor as E, RivusToolInputRejected as F, MemoryScope as G, MemoryBinding as H, RivusToolRisk as I, RIVUS_MEMORY_TOOL_PLUGIN_ID as J, MemoryState as K, requiresToolApproval as L, RivusToolFactoryContext as M, RivusToolGrantSet as N, RivusSkillGrantSet as O, RivusToolIdempotency as P, restrictMemoryScopesForAudience as Q, AgentMemoryAuthority as R, RivusPluginCatalog as S, RivusPluginRegistry as T, MemoryInvocationAudience as U, MEMORY_SCOPES as V, MemoryRecord as W, createMemoryNamespace as X, RIVUS_MEMORY_TOOL_VERSION as Y, createRivusMemoryToolContract as Z, 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, RIVUS_MEMORY_TOOL_ID as q, RivusPluginConformanceReport as r, InvalidRivusPlugin as s, RivusPluginConformanceError as t, RegisteredRivusAutomation as u, RivusAutomationTemplate as v, RivusPluginManifest as w, RivusPlugin as x, RivusAutomationTickContext as y, AgentMemoryIdentity as z };
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
+ }