@segmentstream/agent 0.10.3 → 0.11.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.
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- var version = "0.10.3";
7
+ var version = "0.11.0";
8
8
  function agentBuild(environment = process.env) {
9
9
  return {
10
10
  agent: version,
@@ -20,7 +20,6 @@ export { chooseModel, model, type DynamicModel, type ModelChoice } from "./model
20
20
  export { groupPolicy, effectiveGroupPolicy, DEFAULT_GROUP_POLICY, type GroupPolicy, type GroupPolicyInput, type SmartPolicyInput, type ChatOverrideInput, } from "./lib/group-routing/policy.js";
21
21
  export { addressingReason as groupAddressingReason, conversationKey, type GroupMessageSignals, type AgentMessageSignals, type GroupChannelAdapter, } from "./lib/group-routing/signals.js";
22
22
  export { routeMessage as routeGroupMessage, decisionRouter as groupDecisionRouter, } from "./lib/group-routing/router.js";
23
- export { groupSettings as readGroupSettings, type CloudGroupSettings, } from "./lib/group-routing/settings.js";
24
23
  export { observedMessages as groupObservedMessages, agentMessage as groupAgentMessage, type RecentMessage, type AgentMessage, type ObservedMessage, } from "./lib/group-routing/observed.js";
25
24
  export { archivedRoutingMessages } from "./lib/group-routing/routing-context.js";
26
25
  export { replayRouterPayload } from "./lib/group-routing/replay.js";
@@ -10,7 +10,6 @@ import { chooseModel, model } from "./model.mjs";
10
10
  import { addressingReason, conversationKey } from "./lib/group-routing/signals.mjs";
11
11
  import { conversationAddressing, conversationState } from "./lib/group-routing/conversation.mjs";
12
12
  import { decisionRouter, routeMessage } from "./lib/group-routing/router.mjs";
13
- import { groupSettings } from "./lib/group-routing/settings.mjs";
14
13
  import { agentMessage, observedMessages } from "./lib/group-routing/observed.mjs";
15
14
  import { archivedRoutingMessages } from "./lib/group-routing/routing-context.mjs";
16
15
  import { replayRouterPayload } from "./lib/group-routing/replay.mjs";
@@ -21,4 +20,4 @@ const segmentstream = Object.assign(extension, {
21
20
  model: (choice) => model(choice ?? (() => extension.config.models.chat)),
22
21
  manifestOf
23
22
  });
24
- export { DEFAULT_ADMISSION_LIMITS, DEFAULT_DECISION_MODEL, DEFAULT_GROUP_POLICY, DEFAULT_STT_MODEL, SegmentStreamAgentConfigError, archivedRoutingMessages, chooseModel, conversationKey, debounceBurst, segmentstream as default, segmentstream, effectiveGroupPolicy, addressingReason as groupAddressingReason, agentMessage as groupAgentMessage, conversationAddressing as groupConversationAddressing, conversationState as groupConversationState, decisionRouter as groupDecisionRouter, observedMessages as groupObservedMessages, groupPolicy, manifestOf, model, groupSettings as readGroupSettings, replayRouterPayload, routeMessage as routeGroupMessage, routingBurst };
23
+ export { DEFAULT_ADMISSION_LIMITS, DEFAULT_DECISION_MODEL, DEFAULT_GROUP_POLICY, DEFAULT_STT_MODEL, SegmentStreamAgentConfigError, archivedRoutingMessages, chooseModel, conversationKey, debounceBurst, segmentstream as default, segmentstream, effectiveGroupPolicy, addressingReason as groupAddressingReason, agentMessage as groupAgentMessage, conversationAddressing as groupConversationAddressing, conversationState as groupConversationState, decisionRouter as groupDecisionRouter, observedMessages as groupObservedMessages, groupPolicy, manifestOf, model, replayRouterPayload, routeMessage as routeGroupMessage, routingBurst };
@@ -4,5 +4,5 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../_chunks/build-metadata-CBYp34h5.mjs";
7
+ import { t as agentBuild } from "../../_chunks/build-metadata-F_kHphOG.mjs";
8
8
  export { agentBuild };
@@ -23,9 +23,6 @@ export interface SmartPolicy {
23
23
  readonly context: {
24
24
  readonly messages: number;
25
25
  readonly includeAgentDescription: boolean;
26
- readonly includeAgentInstructions: boolean | {
27
- readonly maxChars: number;
28
- };
29
26
  readonly includeChatGuidance: boolean;
30
27
  readonly includeParticipants: boolean;
31
28
  };
@@ -77,5 +74,5 @@ export declare function groupPolicy(input?: GroupPolicyInput, aliases?: {
77
74
  /** Dynamic defaults change only when inherited from the platform; authored fields retain precedence. */
78
75
  export declare function overlaySmartPolicy(input: SmartPolicyInput | undefined, base: GroupPolicy): SmartPolicy;
79
76
  export declare const DEFAULT_GROUP_POLICY: GroupPolicy;
80
- /** Agent -> Cloud override -> pinned chat -> registry. Provider-specific switches only map signals. */
81
- export declare function effectiveGroupPolicy(base: GroupPolicy, key: string, registry?: ChatOverrideInput, cloud?: GroupPolicyInput): GroupPolicy;
77
+ /** Agent -> chat -> chat scope, as `groups` authors them. Provider switches only map signals. */
78
+ export declare function effectiveGroupPolicy(base: GroupPolicy, key: string): GroupPolicy;
@@ -40,7 +40,6 @@ function smartPolicy(input = {}, base) {
40
40
  context: {
41
41
  messages: conversation ? 60 : 30,
42
42
  includeAgentDescription: true,
43
- includeAgentInstructions: false,
44
43
  includeChatGuidance: true,
45
44
  includeParticipants: true,
46
45
  ...base?.context,
@@ -157,30 +156,10 @@ function overlaySmartPolicy(input, base) {
157
156
  });
158
157
  }
159
158
  const DEFAULT_GROUP_POLICY = groupPolicy();
160
- function effectiveGroupPolicy(base, key, registry, cloud) {
161
- let result = cloud === void 0 ? base : {
162
- ...base,
163
- mode: cloud.mode ?? base.mode,
164
- smart: overlaySmartPolicy(cloud.smart, base),
165
- chats: {
166
- ...base.chats,
167
- ...cloud.chats
168
- },
169
- observability: {
170
- ...base.observability,
171
- ...cloud.observability
172
- },
173
- sources: {
174
- ...base.sources,
175
- ...sources(cloud, "cloud")
176
- }
177
- };
159
+ function effectiveGroupPolicy(base, key) {
160
+ let result = base;
178
161
  const parent = key.includes("/") ? result.chats[key.slice(0, key.indexOf("/"))] : void 0;
179
- for (const layer of [
180
- parent,
181
- result.chats[key],
182
- registry
183
- ]) if (layer !== void 0) result = {
162
+ for (const layer of [parent, result.chats[key]]) if (layer !== void 0) result = {
184
163
  ...result,
185
164
  mode: layer.mode ?? result.mode,
186
165
  smart: overlaySmartPolicy(layer.smart, result),
@@ -190,7 +169,7 @@ function effectiveGroupPolicy(base, key, registry, cloud) {
190
169
  },
191
170
  sources: {
192
171
  ...result.sources,
193
- ...sources(layer, layer === registry ? "registry" : "agent.chat")
172
+ ...sources(layer, "agent.chat")
194
173
  }
195
174
  };
196
175
  const thresholds = result.smart.thresholds;
@@ -14,7 +14,6 @@ export interface RouteQuestion {
14
14
  readonly processingAt?: string;
15
15
  readonly messagesToClassify?: ReadonlyArray<ObservedMessage>;
16
16
  readonly signals?: GroupMessageSignals;
17
- readonly agentInstructions?: string;
18
17
  /** The agent's own description, so the model knows what it can be asked for. */
19
18
  readonly agent: string;
20
19
  readonly agentIdentity?: Partial<BotIdentity> & {
@@ -121,7 +121,6 @@ function conversationContext(question) {
121
121
  }));
122
122
  return {
123
123
  agent: policy.smart.context.includeAgentDescription ? question.agent.slice(0, 4e3) : "",
124
- ...policy.smart.context.includeAgentInstructions ? { agent_instructions: (question.agentInstructions ?? "").slice(0, typeof policy.smart.context.includeAgentInstructions === "object" ? policy.smart.context.includeAgentInstructions.maxChars : 6e3) } : {},
125
124
  agent_identity: JSON.stringify({
126
125
  display_name: bot?.displayName ?? null,
127
126
  username: bot?.username ?? null,
@@ -1,4 +1,3 @@
1
- import { type ChatOverrideInput } from "@segmentstream-cloud/ontology/groups";
2
1
  import type { AdmissionLimitsInput } from "../config.js";
3
2
  import type { RuntimeToken } from "./runtime-token.js";
4
3
  /**
@@ -69,8 +68,6 @@ export interface ChatAccount {
69
68
  }
70
69
  /** A group chat in the ontology's `agent_chat` registry, with what members said it is for. */
71
70
  export interface AgentChat {
72
- readonly routing?: ChatOverrideInput;
73
- readonly scope?: string;
74
71
  readonly id: string;
75
72
  readonly title: string;
76
73
  readonly purpose: string | null;
@@ -5,7 +5,6 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { redactDiagnostic } from "./diagnostics.mjs";
8
- import { groupPolicyIssues } from "@segmentstream-cloud/ontology/groups";
9
8
  var AgentIdentityError = class extends Error {
10
9
  name = "AgentIdentityError";
11
10
  code;
@@ -94,22 +93,11 @@ function agentChat(value) {
94
93
  code: "invalid_response",
95
94
  message: "The ontology service answered the chat report with an invalid body."
96
95
  });
97
- const override = {
98
- ...isRecord(value.routing) ? value.routing : {},
99
- ...isRecord(value.participants) ? { participants: value.participants } : {}
100
- };
101
- const valid = groupPolicyIssues(override, true).length === 0;
102
- if (!valid) console.error("[segmentstream] invalid chat routing override", {
103
- chatId: value.id,
104
- issues: groupPolicyIssues(override, true)
105
- });
106
96
  return {
107
97
  id: value.id,
108
98
  title: value.title,
109
99
  purpose: value.purpose,
110
- whenToUse: value.whenToUse,
111
- ...typeof value.scope === "string" ? { scope: value.scope } : {},
112
- ...valid && Object.keys(override).length > 0 ? { routing: override } : {}
100
+ whenToUse: value.whenToUse
113
101
  };
114
102
  }
115
103
  async function refusal(response, call) {
@@ -11,10 +11,9 @@ import { chooseModel } from "../../model.mjs";
11
11
  import { groupRoutingHealth } from "../group-routing/health.mjs";
12
12
  import { decisionRouter } from "../group-routing/router.mjs";
13
13
  import { runtimeToken } from "../runtime-token.mjs";
14
- import { groupSettings } from "../group-routing/settings.mjs";
15
14
  import { conversations } from "../conversations.mjs";
16
15
  import { archivedRoutingMessages } from "../group-routing/routing-context.mjs";
17
- import { t as agentBuild } from "../../../_chunks/build-metadata-CBYp34h5.mjs";
16
+ import { t as agentBuild } from "../../../_chunks/build-metadata-F_kHphOG.mjs";
18
17
  import { confirmationLocale } from "./confirmation-text.mjs";
19
18
  import { telegramSendScope } from "./send-queue.mjs";
20
19
  import { d as failureText, h as withDeliveryLocale, i as withReplacedText, m as safeTelegramFetch, n as currentInboundRequest, p as reportTelegramError, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-BrWspFw5.mjs";
@@ -71,11 +70,6 @@ const eveInteractions = async (sessionId) => {
71
70
  function segmentstreamTelegram(options) {
72
71
  const environment = options.environment ?? process.env;
73
72
  const token = options.token ?? runtimeToken;
74
- const readGroups = groupSettings({
75
- environment,
76
- token,
77
- fetch: options.fetch
78
- });
79
73
  const observed = options.observed ?? observedMessages(60);
80
74
  const readHistory = options.history ?? eveHistory;
81
75
  const readInteractions = options.history ?? eveInteractions;
@@ -183,7 +177,6 @@ function segmentstreamTelegram(options) {
183
177
  limit: 200,
184
178
  includeDecisions: true
185
179
  })).events, 100),
186
- cloudGroups: options.groups === void 0 ? void 0 : readGroups,
187
180
  signalSettings: settings().groups,
188
181
  recoverHeldApprovals: options.confirmationMode?.() === "deferred",
189
182
  ...settings().attachmentLifecycle === void 0 ? {} : { lifecycle: (principal, memberId, message) => attachmentLifecycle({
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../../_chunks/build-metadata-CBYp34h5.mjs";
7
+ import { t as agentBuild } from "../../../_chunks/build-metadata-F_kHphOG.mjs";
8
8
  import { runtimeRequestFailure } from "./runtime-request.mjs";
9
9
  import { GET } from "eve/channels";
10
10
  const HEALTH_ROUTE = "/eve/v1/telegram/health";
@@ -1,5 +1,4 @@
1
1
  import type { RecentMessage } from "../group-routing/observed.js";
2
- import type { CloudGroupSettings } from "../group-routing/settings.js";
3
2
  import { type GroupPolicy } from "../group-routing/policy.js";
4
3
  import type { TelegramSettings } from "../../config.js";
5
4
  import { attachmentLifecycle } from "./lifecycle.js";
@@ -46,7 +45,6 @@ export interface InboundDependencies {
46
45
  readonly decisionModel?: string;
47
46
  readonly groups?: GroupPolicy;
48
47
  readonly recentConversation?: (chatId: string, threadId?: string) => Promise<ReadonlyArray<RecentMessage>>;
49
- readonly cloudGroups?: () => Promise<CloudGroupSettings | undefined>;
50
48
  readonly signalSettings?: TelegramSettings["groups"];
51
49
  /** Recover old held sessions only when the workspace has chosen non-blocking confirmations. */
52
50
  readonly recoverHeldApprovals?: boolean;
@@ -461,12 +461,10 @@ async function handleInboundMessage(input) {
461
461
  const questionHistory = owner === void 0 || dependencies.history === void 0 ? [] : await dependencies.history(owner.id);
462
462
  await report;
463
463
  const policySignals = telegramSignals(sent, bot, dependencies.signalSettings);
464
- const cloudGroups = await dependencies.cloudGroups?.();
465
- const registryChat = dependencies.chats.chat(sent.chat.id);
466
464
  const groups = effectiveGroupPolicy(dependencies.groups ?? groupPolicy({}, {
467
465
  mode: dependencies.policy,
468
466
  model: dependencies.decisionModel
469
- }), conversationKey(policySignals), registryChat?.scope !== void 0 && registryChat.scope !== policySignals.conversation.scope ? void 0 : registryChat?.routing, cloudGroups?.settings);
467
+ }), conversationKey(policySignals));
470
468
  const conversationPolicy = group && groups.smart.engagement.policy === "conversation";
471
469
  const agentAliases = [...groups.smart.engagement.agentAliases, ...[
472
470
  bot?.username,
@@ -588,7 +586,6 @@ async function handleInboundMessage(input) {
588
586
  }
589
587
  },
590
588
  agent: await input.request?.agentDescription() ?? "",
591
- agentInstructions: cloudGroups?.instructions,
592
589
  agentIdentity: {
593
590
  ...bot,
594
591
  displayName: bot?.displayName ?? name,
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../../_chunks/build-metadata-CBYp34h5.mjs";
7
+ import { t as agentBuild } from "../../../_chunks/build-metadata-F_kHphOG.mjs";
8
8
  import { object } from "../confirmation-description.mjs";
9
9
  import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-BrWspFw5.mjs";
10
10
  import { needsConfirmation } from "../confirmations.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@segmentstream/agent",
3
- "version": "0.10.3",
3
+ "version": "0.11.0",
4
4
  "description": "Mount a SegmentStream workspace's agent on eve: the ontology as tools, acting as the member who writes, and Telegram through the workspace's connection.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "SegmentStream",
@@ -62,7 +62,7 @@
62
62
  },
63
63
  "dependencies": {
64
64
  "@chat-adapter/telegram": "4.41.0",
65
- "@segmentstream-cloud/ontology": "0.45.0",
65
+ "@segmentstream-cloud/ontology": "0.47.0",
66
66
  "@vercel/oidc": "^3.8.4",
67
67
  "ai": "^7.0.128",
68
68
  "csv-parse": "^7.0.3",
@@ -1,14 +0,0 @@
1
- import { type GroupPolicyInput } from "@segmentstream-cloud/ontology/groups";
2
- import { type Environment } from "../environment.js";
3
- import { type RuntimeToken } from "../runtime-token.js";
4
- export interface CloudGroupSettings {
5
- readonly settings: GroupPolicyInput;
6
- readonly instructions?: string;
7
- }
8
- /** Bounded request-scoped identity, one policy refresh per minute, last known override on transient failure. */
9
- export declare function groupSettings(input?: {
10
- readonly environment?: Environment;
11
- readonly token?: RuntimeToken;
12
- readonly fetch?: typeof fetch;
13
- readonly now?: () => number;
14
- }): () => Promise<CloudGroupSettings | undefined>;
@@ -1,58 +0,0 @@
1
- import { fileURLToPath as __eveFileURLToPath } from "node:url";
2
- import { dirname as __eveDirname } from "node:path";
3
- import { createRequire as __eveCreateRequire } from "node:module";
4
- const __filename = __eveFileURLToPath(import.meta.url);
5
- __eveDirname(__filename);
6
- __eveCreateRequire(import.meta.url);
7
- import { proxyEnvironment } from "../environment.mjs";
8
- import { runtimeToken } from "../runtime-token.mjs";
9
- import { groupPolicyIssues } from "@segmentstream-cloud/ontology/groups";
10
- function groupSettings(input = {}) {
11
- let cached;
12
- let expires = 0;
13
- let etag;
14
- let pending;
15
- const now = input.now ?? Date.now;
16
- return async () => {
17
- if (now() < expires) return cached;
18
- if (pending !== void 0) return pending;
19
- pending = (async () => {
20
- try {
21
- const env = proxyEnvironment(input.environment);
22
- const identity = await (input.token ?? runtimeToken)();
23
- const workspacePath = `/api/internal/v1/workspaces/${encodeURIComponent(env.workspaceId)}`;
24
- const response = await (input.fetch ?? fetch)(`${env.segmentstreamUrl}${workspacePath}/agent/groups/effective`, {
25
- redirect: "error",
26
- headers: {
27
- "x-segmentstream-organization-id": env.organizationId,
28
- "x-segmentstream-runtime-identity": identity,
29
- ...etag === void 0 ? {} : { "if-none-match": etag }
30
- },
31
- signal: AbortSignal.timeout(5e3)
32
- });
33
- if (response.status === 304) return cached;
34
- if (response.status === 404) return cached;
35
- if (!response.ok) throw new Error(`Group settings read failed (${response.status}); request ${response.headers.get("x-request-id") ?? "unknown"}.`);
36
- const value = await response.json();
37
- if (value.settings === void 0 || groupPolicyIssues(value.settings).length > 0) throw new Error("Invalid group settings response.");
38
- cached = {
39
- settings: value.settings,
40
- ...typeof value.instructions === "string" ? { instructions: value.instructions.slice(0, 6e3) } : {}
41
- };
42
- etag = response.headers.get("etag") ?? (typeof value.version === "string" ? `"${value.version}"` : void 0);
43
- return cached;
44
- } catch (error) {
45
- console.error("[segmentstream] group settings refresh failed", { error });
46
- return cached;
47
- } finally {
48
- expires = now() + 6e4;
49
- }
50
- })();
51
- try {
52
- return await pending;
53
- } finally {
54
- pending = void 0;
55
- }
56
- };
57
- }
58
- export { groupSettings };