@segmentstream/agent 0.30.0 → 0.31.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 CHANGED
@@ -64,17 +64,22 @@ export default segmentstream(config);
64
64
  import { defineAgent } from "eve";
65
65
  import { segmentstream } from "@segmentstream/agent";
66
66
 
67
+ import config from "../segmentstream.json";
68
+
67
69
  export default defineAgent({
68
70
  defaultTools: false,
69
- model: segmentstream.model(),
71
+ model: segmentstream.model(config.models.chat),
70
72
  reasoning: "medium",
71
73
  limits: { sessionUsage: ({ window }) => (window.costUsd ?? 0) >= 2 },
72
74
  });
73
75
  ```
74
76
 
75
- `segmentstream.model()` resolves on `session.started` from `models.chat` in `agent/segmentstream.json`
76
- (`{ "default", "byRole", "preview" }`), where the platform reads it too; an inline
77
- `segmentstream.model({ default, byRole, preview })` works the same. On a preview deployment it returns `preview`
77
+ `segmentstream.model(choice)` resolves on `session.started` from `models.chat` of
78
+ `agent/segmentstream.json` (`{ "default", "byRole", "preview" }`), where the platform reads it too;
79
+ an inline `segmentstream.model({ default, byRole, preview })` works the same. `agent.ts` passes the
80
+ choice because eve binds the extension's configuration only to the modules it bundles for the
81
+ mount: code outside the extension never sees it. A missing or invalid choice fails when `agent.ts`
82
+ loads. On a preview deployment it returns `preview`
78
83
  when set. Otherwise it returns the model of the first `byRole` entry whose role the member holds, in
79
84
  the order written, and `default` when none matches. The roles come from the member's pairing, not
80
85
  from the message. The model is never switched mid-session, which keeps the provider's prompt cache.
@@ -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.30.0";
7
+ var version = "0.31.0";
8
8
  function agentBuild(environment = process.env) {
9
9
  return {
10
10
  agent: version,
@@ -196,7 +196,10 @@ export interface SegmentStreamAgentConfig extends AdmissionSettings {
196
196
  readonly telegram: TelegramSettings | null;
197
197
  };
198
198
  readonly models: {
199
- /** `null` when `agent.ts` passes the choice to `segmentstream.model()` itself. */
199
+ /**
200
+ * `null` when the JSON sets none. The platform reads it at deploy; `agent.ts` passes the same
201
+ * value to `segmentstream.model()`, which never reads the mount's configuration.
202
+ */
200
203
  readonly chat: ChatModelChoice | null;
201
204
  readonly stt: string | false;
202
205
  readonly imageDescription: string | false | null;
@@ -227,6 +230,11 @@ export declare class SegmentStreamAgentConfigError extends Error {
227
230
  readonly name = "SegmentStreamAgentConfigError";
228
231
  constructor(issues: ReadonlyArray<ConfigIssue>);
229
232
  }
233
+ /**
234
+ * The chat model choice `agent.ts` passes to `segmentstream.model()`, validated like `models.chat`
235
+ * of `agent/segmentstream.json`, where it normally comes from.
236
+ */
237
+ export declare function chatModelChoiceOf(value: unknown): ChatModelChoice;
230
238
  /** Exact historical pins retain the pre-0.13 presentation contract at the archive boundary. */
231
239
  export declare function isLegacyAgentArchive(version: string | undefined): boolean;
232
240
  /** Validates the authored configuration and applies the defaults. */
@@ -297,6 +297,13 @@ function chatModelChoice(value, issues) {
297
297
  ...preview === void 0 ? {} : { preview }
298
298
  };
299
299
  }
300
+ function chatModelChoiceOf(value) {
301
+ const issues = [];
302
+ const choice = chatModelChoice(value, issues);
303
+ if (issues.length > 0) throw new SegmentStreamAgentConfigError(issues);
304
+ if (choice === null) throw new TypeError("segmentstream.model() needs the chat model choice: pass models.chat of agent/segmentstream.json, as in segmentstream.model(config.models.chat).");
305
+ return choice;
306
+ }
300
307
  function isSessionScope(value) {
301
308
  return SESSION_SCOPES.some((scope) => scope === value);
302
309
  }
@@ -717,4 +724,4 @@ function manifestOf(config) {
717
724
  if (validation.issues !== void 0) throw new SegmentStreamAgentConfigError(validation.issues);
718
725
  return validation.value;
719
726
  }
720
- export { ADMISSION_REPLY_KEYS, DEFAULT_ADMISSION_LIMITS, DEFAULT_ATTACHMENTS_MODEL, DEFAULT_DECISION_MODEL, DEFAULT_IMAGE_DESCRIPTION_MODEL, DEFAULT_STT_MODEL, SESSION_SCOPES, SegmentStreamAgentConfigError, TELEGRAM_POLICIES, configSchema, isLegacyAgentArchive, manifestOf, validateConfig };
727
+ export { ADMISSION_REPLY_KEYS, DEFAULT_ADMISSION_LIMITS, DEFAULT_ATTACHMENTS_MODEL, DEFAULT_DECISION_MODEL, DEFAULT_IMAGE_DESCRIPTION_MODEL, DEFAULT_STT_MODEL, SESSION_SCOPES, SegmentStreamAgentConfigError, TELEGRAM_POLICIES, chatModelChoiceOf, configSchema, isLegacyAgentArchive, manifestOf, validateConfig };
@@ -1,5 +1,5 @@
1
1
  import { manifestOf } from "./config.js";
2
- import { type DynamicModel, type ModelChoice } from "./model.js";
2
+ import { model } from "./model.js";
3
3
  export declare const segmentstream: import("eve/extension").ExtensionHandle<{
4
4
  readonly "~standard": {
5
5
  readonly version: 1;
@@ -16,7 +16,7 @@ export declare const segmentstream: import("eve/extension").ExtensionHandle<{
16
16
  };
17
17
  };
18
18
  }> & {
19
- model: (choice?: ModelChoice) => DynamicModel;
19
+ model: typeof model;
20
20
  manifestOf: typeof manifestOf;
21
21
  };
22
22
  export default segmentstream;
@@ -17,7 +17,7 @@ import { routingBurst } from "./lib/group-routing/burst.mjs";
17
17
  import { defineExtension } from "eve/extension";
18
18
  const extension = defineExtension({ config: configSchema });
19
19
  const segmentstream = Object.assign(extension, {
20
- model: (choice) => model(choice ?? (() => extension.config.models.chat)),
20
+ model,
21
21
  manifestOf
22
22
  });
23
23
  export { DEFAULT_ADMISSION_LIMITS, DEFAULT_DECISION_MODEL, DEFAULT_GROUP_POLICY, DEFAULT_STT_MODEL, SegmentStreamAgentConfigError, archivedRoutingMessages, chooseModel, conversationKey, segmentstream as default, segmentstream, effectiveGroupPolicy, addressingReason as groupAddressingReason, agentMessage as groupAgentMessage, conversationAddressing as groupConversationAddressing, decisionRouter as groupDecisionRouter, groupPolicy, manifestOf, model, replayRouterPayload, routeMessage as routeGroupMessage, routingBurst };
@@ -4,4 +4,4 @@ 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
- export { t as agentBuild } from "../../_chunks/build-metadata-Dgh-X4S8.mjs";
7
+ export { t as agentBuild } from "../../_chunks/build-metadata-CZuxPOVF.mjs";
@@ -10,7 +10,7 @@ import { groupRoutingHealth } from "../group-routing/health.mjs";
10
10
  import { dispatchStructuredMessage, structuredMessage } from "./structured.mjs";
11
11
  import { handleWorkspaceCallback, isWorkspaceCallback } from "./callbacks.mjs";
12
12
  import { telegramText, withTelegramTexts } from "./texts.mjs";
13
- import { t as agentBuild } from "../../../_chunks/build-metadata-Dgh-X4S8.mjs";
13
+ import { t as agentBuild } from "../../../_chunks/build-metadata-CZuxPOVF.mjs";
14
14
  import { attachmentLifecycle } from "./lifecycle.mjs";
15
15
  import { manifestOf } from "../../config.mjs";
16
16
  import { gatewayAttachmentDescriber } from "./attachment-description.mjs";
@@ -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-Dgh-X4S8.mjs";
7
+ import { t as agentBuild } from "../../../_chunks/build-metadata-CZuxPOVF.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";
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { d as telegramRuntimeSource, l as principalRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-CPOCTHBa.mjs";
8
- import { t as agentBuild } from "../../../_chunks/build-metadata-Dgh-X4S8.mjs";
8
+ import { t as agentBuild } from "../../../_chunks/build-metadata-CZuxPOVF.mjs";
9
9
  import { n as currentInboundRequest } from "../../../_chunks/inbound-request-Dy7q3T23.mjs";
10
10
  import { object } from "../confirmation-description.mjs";
11
11
  import { needsConfirmation } from "../confirmations.mjs";
@@ -1,6 +1,6 @@
1
1
  import { type AgentModelDefinition, type AgentStaticModelDefinition } from "eve";
2
2
  import type { SessionAuthContext } from "eve/context";
3
- import type { ChatModelChoice } from "./config.js";
3
+ import { type ChatModelChoice } from "./config.js";
4
4
  import { type Environment } from "./lib/environment.js";
5
5
  /** The models `segmentstream.model()` chooses between, as AI Gateway model ids. */
6
6
  export type ModelChoice = ChatModelChoice;
@@ -15,8 +15,11 @@ export declare function chooseModel(input: {
15
15
  /**
16
16
  * The agent's model, chosen once when a session starts from the member's roles and `VERCEL_ENV`.
17
17
  * Choosing once keeps the provider's prompt cache: a switch mid-session re-reads the history at
18
- * full price. The choice is given here, or read when the session starts, from `models.chat` of
19
- * `agent/segmentstream.json` through the mounted extension; a session without either fails to
20
- * start with a message naming the missing setting.
18
+ * full price.
19
+ *
20
+ * `agent.ts` passes the choice, normally `models.chat` of `agent/segmentstream.json`, which the
21
+ * platform reads at deploy. eve binds the mount's configuration only to the modules it bundles for
22
+ * that mount, and `agent.ts` is outside it, so the choice is never read from the mount. A missing or
23
+ * invalid choice fails when `agent.ts` loads, not on the first message.
21
24
  */
22
- export declare function model(choice: ModelChoice | (() => ModelChoice | null)): DynamicModel;
25
+ export declare function model(choice: ModelChoice): DynamicModel;
@@ -4,6 +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 { chatModelChoiceOf } from "./config.mjs";
7
8
  import { isPreview } from "./lib/environment.mjs";
8
9
  import { a as rolesOf } from "../_chunks/principal-CPOCTHBa.mjs";
9
10
  import { runs } from "eve/events";
@@ -16,11 +17,10 @@ function chooseModel(input) {
16
17
  return choice.default;
17
18
  }
18
19
  function model(choice) {
20
+ const chosen = chatModelChoiceOf(choice);
19
21
  return defineDynamic((context) => context.memo(context.session.id, () => {
20
22
  const previous = runs(context.view).findLast((run) => run.turnId !== void 0 && run.modelId !== void 0)?.modelId;
21
23
  if (previous !== void 0) return previous;
22
- const chosen = typeof choice === "function" ? choice() : choice;
23
- if (chosen === null) throw new Error("segmentstream.model() has no model to choose from: set models.chat in agent/segmentstream.json or pass the choice to segmentstream.model().");
24
24
  return chooseModel({
25
25
  choice: chosen,
26
26
  principal: context.session.auth.initiator ?? context.session.auth.current
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@segmentstream/agent",
3
- "version": "0.30.0",
3
+ "version": "0.31.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",