@segmentstream/agent 0.10.4 → 0.12.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 +1 -1
- package/dist/_chunks/{build-metadata-CFAnvrjf.mjs → build-metadata-SU1WsppW.mjs} +1 -1
- package/dist/extension/extension.d.ts +0 -1
- package/dist/extension/extension.mjs +1 -2
- package/dist/extension/instructions.md +10 -0
- package/dist/extension/lib/build-metadata.mjs +1 -1
- package/dist/extension/lib/group-routing/policy.d.ts +2 -5
- package/dist/extension/lib/group-routing/policy.mjs +4 -25
- package/dist/extension/lib/group-routing/router.d.ts +0 -1
- package/dist/extension/lib/group-routing/router.mjs +0 -1
- package/dist/extension/lib/identities.d.ts +0 -3
- package/dist/extension/lib/identities.mjs +1 -13
- package/dist/extension/lib/telegram/adapter.mjs +1 -8
- package/dist/extension/lib/telegram/health.mjs +1 -1
- package/dist/extension/lib/telegram/inbound.d.ts +0 -2
- package/dist/extension/lib/telegram/inbound.mjs +1 -4
- package/dist/extension/lib/telegram/lifecycle.mjs +1 -1
- package/package.json +3 -3
- package/dist/extension/lib/group-routing/settings.d.ts +0 -14
- package/dist/extension/lib/group-routing/settings.mjs +0 -58
package/README.md
CHANGED
|
@@ -451,7 +451,7 @@ To reach a local ontology service, set `SEGMENTSTREAM_AGENT_ONTOLOGY_URL=http://
|
|
|
451
451
|
production tokens of the workspace's project, though, so a local run gets the ontology only from a
|
|
452
452
|
local ontology service configured to accept that token.
|
|
453
453
|
|
|
454
|
-
Building the package needs Node.js 24, as eve does: `
|
|
454
|
+
Building the package needs Node.js 24, as eve does: `pnpm run build` runs `eve extension build`,
|
|
455
455
|
which writes the agent-shaped `dist/extension` tree, its declarations and eve's compatibility
|
|
456
456
|
manifest.
|
|
457
457
|
|
|
@@ -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.
|
|
7
|
+
var version = "0.12.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,
|
|
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 };
|
|
@@ -19,6 +19,16 @@ talking to you, and you act with exactly their permissions.
|
|
|
19
19
|
reload definitions already known for the current ontology hash. Metadata visibility does
|
|
20
20
|
not grant record access. The operation tools are narrowed to the member's current permissions;
|
|
21
21
|
if an operation is missing, say so instead of looking for a way around.
|
|
22
|
+
- When the ontology offers `app_feedback_submit`, the app accepts feedback for its builders.
|
|
23
|
+
Offer to send it when the member wants something no permitted tool, field or data provides, an
|
|
24
|
+
operation is refused for lack of permission, an operation fails unexpectedly or a retryable
|
|
25
|
+
failure persists, or the member says something works badly or asks for something new. Do not
|
|
26
|
+
offer what you can do yourself; offer once per problem. Before submitting, look for the member's
|
|
27
|
+
open `app_feedback` with the same subject. Submit only after the member agrees to the title and
|
|
28
|
+
summary you show in their language, then add each screenshot or file they sent with
|
|
29
|
+
`app_feedback_file_attach`, promoting a chat attachment into it. When a member starts talking to
|
|
30
|
+
you, find their `app_feedback` with `responded_at` set and `seen_at` empty, tell them the
|
|
31
|
+
builders' response, then call `app_feedback_acknowledge` with its `responded_at`.
|
|
22
32
|
Older ontologies without `discover` return the legacy full catalog from `describe`; use that
|
|
23
33
|
available contract. New description results carry `kind` and `hash`.
|
|
24
34
|
- When the current member has permission and gives a clear instruction, act, including necessary
|
|
@@ -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-
|
|
7
|
+
import { t as agentBuild } from "../../_chunks/build-metadata-SU1WsppW.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 ->
|
|
81
|
-
export declare function effectiveGroupPolicy(base: GroupPolicy, key: string
|
|
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
|
|
161
|
-
let result =
|
|
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,
|
|
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-
|
|
16
|
+
import { t as agentBuild } from "../../../_chunks/build-metadata-SU1WsppW.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-
|
|
7
|
+
import { t as agentBuild } from "../../../_chunks/build-metadata-SU1WsppW.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)
|
|
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-
|
|
7
|
+
import { t as agentBuild } from "../../../_chunks/build-metadata-SU1WsppW.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.
|
|
3
|
+
"version": "0.12.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",
|
|
@@ -57,12 +57,12 @@
|
|
|
57
57
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
58
58
|
"lint": "eslint src tests --config ../../eslint.config.mjs",
|
|
59
59
|
"test": "vitest run",
|
|
60
|
-
"prepack": "
|
|
60
|
+
"prepack": "pnpm run build",
|
|
61
61
|
"eval:routing": "tsx tests/routing-eval/cli.ts"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@chat-adapter/telegram": "4.41.0",
|
|
65
|
-
"@segmentstream-cloud/ontology": "0.
|
|
65
|
+
"@segmentstream-cloud/ontology": "0.48.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 };
|