@opengeni/contracts 0.20.0 → 0.21.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/contracts",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "Shared zod schemas and wire-contract types for the OpenGeni API.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
package/src/index.ts CHANGED
@@ -4464,6 +4464,41 @@ export const CapabilityPackSkill = z
4464
4464
  });
4465
4465
  export type CapabilityPackSkill = z.infer<typeof CapabilityPackSkill>;
4466
4466
 
4467
+ // Inline skill content fixed onto one session at creation. It intentionally
4468
+ // uses the exact same validated directory shape as a pack skill, but has a
4469
+ // different semantic owner and lifecycle. Session readers can inspect it; it
4470
+ // is configuration, never a secret store.
4471
+ export const SessionSkill = CapabilityPackSkill;
4472
+ export type SessionSkill = z.infer<typeof SessionSkill>;
4473
+
4474
+ export const SessionSkills = z
4475
+ .array(SessionSkill)
4476
+ .max(32)
4477
+ .transform((skills, ctx) => {
4478
+ const selected = new Map<string, { fingerprint: string; skill: SessionSkill }>();
4479
+ for (const skill of skills) {
4480
+ const key = skill.name.toLowerCase();
4481
+ const fingerprint = JSON.stringify({
4482
+ description: skill.description ?? null,
4483
+ files: [...skill.files]
4484
+ .sort((left, right) => left.path.localeCompare(right.path))
4485
+ .map(({ path, content }) => ({ path, content })),
4486
+ });
4487
+ const existing = selected.get(key);
4488
+ if (!existing) {
4489
+ selected.set(key, { fingerprint, skill });
4490
+ continue;
4491
+ }
4492
+ if (existing.fingerprint !== fingerprint) {
4493
+ ctx.addIssue({
4494
+ code: "custom",
4495
+ message: `conflicting session skill definitions: ${skill.name}`,
4496
+ });
4497
+ }
4498
+ }
4499
+ return [...selected.values()].map(({ skill }) => skill);
4500
+ });
4501
+
4467
4502
  function isSafePackSkillRelativePath(path: string): boolean {
4468
4503
  if (path.startsWith("/") || path.includes("\\")) {
4469
4504
  return false;
@@ -4727,15 +4762,16 @@ export const CreateConnectionRequest = z.object({
4727
4762
  });
4728
4763
  export type CreateConnectionRequest = z.infer<typeof CreateConnectionRequest>;
4729
4764
 
4730
- /**
4731
- * Write-only Slack bot installation input. `token` is accepted only by the
4732
- * dedicated validated endpoint and is never represented in a response schema.
4733
- */
4734
- export const ConnectOpenGeniSlackBotRequest = z.object({
4735
- token: z.string().trim().startsWith("xoxb-").max(8192),
4765
+ export const OpenGeniSlackBotInstallRequest = z.object({
4736
4766
  connectionId: z.string().uuid().optional(),
4737
4767
  });
4738
- export type ConnectOpenGeniSlackBotRequest = z.infer<typeof ConnectOpenGeniSlackBotRequest>;
4768
+ export type OpenGeniSlackBotInstallRequest = z.infer<typeof OpenGeniSlackBotInstallRequest>;
4769
+
4770
+ export const OpenGeniSlackBotInstallStart = z.object({
4771
+ authorizationUrl: z.string().url(),
4772
+ expiresAt: z.string().datetime({ offset: true }),
4773
+ });
4774
+ export type OpenGeniSlackBotInstallStart = z.infer<typeof OpenGeniSlackBotInstallStart>;
4739
4775
 
4740
4776
  export const UpdateConnectionRequest = z.object({
4741
4777
  providerDomain: z.string().min(1).optional(),
@@ -4887,15 +4923,15 @@ export const CapabilityCatalogItem = z.object({
4887
4923
  runtime: CapabilityRuntime.default({ available: false, notes: null }),
4888
4924
  enabled: z.boolean().default(false),
4889
4925
  enabledReason: z.string().nullable().default(null),
4890
- // The connection backing this enabled installation, when the enable-time
4891
- // connectionRef resolved to one (null for header/credential-free items
4892
- // that means "no connection involved", not "broken"). Lets the UI match
4893
- // connection health by id instead of guessing from providerDomain alone.
4926
+ // The non-secret connection binding stored with an enabled installation.
4927
+ // Workspace refs retain an exact row id. Subject refs deliberately omit it:
4928
+ // each caller resolves their own visible row by provider/kind at runtime.
4894
4929
  connectionRef: z
4895
4930
  .object({
4896
- connectionId: z.string().min(1),
4931
+ connectionId: z.string().min(1).optional(),
4897
4932
  providerDomain: z.string().min(1),
4898
4933
  kind: z.string().min(1),
4934
+ subjectScope: z.enum(["workspace", "subject"]).optional(),
4899
4935
  })
4900
4936
  .nullable()
4901
4937
  .default(null),
@@ -5011,6 +5047,7 @@ export const Session = z.object({
5011
5047
  // null when the session carried none.
5012
5048
  instructions: z.string().nullable(),
5013
5049
  resources: z.array(ResourceRef),
5050
+ skills: SessionSkills.default([]),
5014
5051
  tools: z.array(ToolRef),
5015
5052
  // Origin of the persisted tool allow-list. Optional for rolling client
5016
5053
  // compatibility; current servers emit it and legacy rows map to `legacy`.
@@ -6016,6 +6053,7 @@ export const WorkspaceCaptureDegradedReason = z.enum([
6016
6053
  "repository_discovery_command_failed",
6017
6054
  "repository_discovery_timed_out",
6018
6055
  "repository_discovery_result_limit_exceeded",
6056
+ "repository_read_unavailable",
6019
6057
  ]);
6020
6058
  export type WorkspaceCaptureDegradedReason = z.infer<typeof WorkspaceCaptureDegradedReason>;
6021
6059
 
@@ -7284,6 +7322,9 @@ export const CreateSessionRequest = withVariableSetIdAlias({
7284
7322
  // authoritative. Top-level omission remains []. Presence is resolved from
7285
7323
  // the raw request because this Zod default erases absent-vs-empty.
7286
7324
  resources: z.array(ResourceRef).default([]),
7325
+ // Inline skills are fixed onto the session. Child omission inherits the
7326
+ // trusted parent's selection; an explicit array, including [], wins.
7327
+ skills: SessionSkills.default([]),
7287
7328
  // The same child omission rule applies to selected MCP tool refs. Top-level
7288
7329
  // omission still applies workspace-default capability MCP tools; explicit []
7289
7330
  // suppresses those defaults (the first-party OpenGeni server remains added).