@quantiya/codevibe-core 2.0.88 → 2.0.89

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.
@@ -25289,11 +25289,23 @@ var AppSyncClient = class _AppSyncClient {
25289
25289
  sessionId,
25290
25290
  lastHeartbeatAt: heartbeatAt
25291
25291
  });
25292
- return this.heartbeatTokens.get(sessionId) !== token4 || refreshed.status !== "ACTIVE" /* ACTIVE */ && (await this.updateSession({
25292
+ if (this.heartbeatTokens.get(sessionId) !== token4 || refreshed.status !== "ACTIVE" /* ACTIVE */ && (await this.updateSession({
25293
25293
  sessionId,
25294
25294
  lastHeartbeatAt: heartbeatAt,
25295
25295
  status: "ACTIVE" /* ACTIVE */
25296
- }), this.heartbeatTokens.get(sessionId) !== token4) ? "stopped" : (logger.debug("[AppSyncClient] Heartbeat sent", { sessionId }), "confirmed");
25296
+ }), this.heartbeatTokens.get(sessionId) !== token4))
25297
+ return "stopped";
25298
+ if (this.syncDisplayListeners.size > 0 && this.authenticated && this.currentUserId) {
25299
+ let userId = this.currentUserId;
25300
+ if (Array.from(this.syncDisplayListeners).some(
25301
+ (entry5) => entry5.userId === userId
25302
+ ) && !this.companionSyncStatusSnapshot(userId)) {
25303
+ let refreshAbort = new AbortController(), refreshDeadline = setTimeout(() => refreshAbort.abort(), 4500);
25304
+ refreshDeadline.unref?.(), this.refreshCompanionSyncDisplayOnMaintenance(userId, refreshAbort.signal).catch(() => {
25305
+ }).finally(() => clearTimeout(refreshDeadline));
25306
+ }
25307
+ }
25308
+ return logger.debug("[AppSyncClient] Heartbeat sent", { sessionId }), "confirmed";
25297
25309
  } catch (error) {
25298
25310
  return logger.warn("[AppSyncClient] Heartbeat failed", { sessionId, error }), isRetiredSessionError(error) ? "retired" : "failed";
25299
25311
  }
@@ -28797,22 +28809,43 @@ var LOCAL_GEMMA_ALLOWED_OUTPUT_KEYS = /* @__PURE__ */ new Set([
28797
28809
  // would throw "included unsupported keys" on every browse decision.
28798
28810
  "browseUrls",
28799
28811
  "browseQuery"
28800
- ]), LOCAL_GEMMA_NULLABLE_OUTPUT_KEYS = ["clarifying_question", "advisory_summary", "browseUrls", "browseQuery"];
28801
- function buildLocalGemmaDecisionJsonSchema() {
28812
+ ]), LOCAL_GEMMA_NULLABLE_OUTPUT_KEYS = ["clarifying_question", "advisory_summary", "browseUrls", "browseQuery"], LOCAL_GEMMA_DECISION_REQUIRED_KEYS = ["rationale", "clarifying_question", "advisory_summary", "browseUrls", "browseQuery", "action"], LOCAL_GEMMA_FIELD_CARRYING_ACTIONS = /* @__PURE__ */ new Set(["browse", "ask_user", "advisory_response"]);
28813
+ function decisionBranch(actions, fields) {
28802
28814
  return {
28803
28815
  type: "object",
28804
28816
  properties: {
28805
28817
  rationale: { type: "string" },
28806
- clarifying_question: { type: ["string", "null"] },
28807
- advisory_summary: { type: ["string", "null"] },
28808
- browseUrls: { type: ["array", "null"], items: { type: "string" } },
28809
- browseQuery: { type: ["string", "null"] },
28810
- action: { type: "string", enum: [...localGemmaAllowedActions()] }
28818
+ clarifying_question: fields.clarifying_question,
28819
+ advisory_summary: fields.advisory_summary,
28820
+ browseUrls: fields.browseUrls,
28821
+ browseQuery: fields.browseQuery,
28822
+ action: { type: "string", enum: actions }
28811
28823
  },
28812
- required: ["rationale", "clarifying_question", "advisory_summary", "browseUrls", "browseQuery", "action"],
28824
+ required: [...LOCAL_GEMMA_DECISION_REQUIRED_KEYS],
28813
28825
  additionalProperties: !1
28814
28826
  };
28815
28827
  }
28828
+ function buildLocalGemmaDecisionJsonSchema() {
28829
+ let nul = { type: "null" }, otherActions = [...localGemmaAllowedActions()].filter((a) => !LOCAL_GEMMA_FIELD_CARRYING_ACTIONS.has(a));
28830
+ return {
28831
+ anyOf: [
28832
+ decisionBranch(["browse"], {
28833
+ clarifying_question: nul,
28834
+ advisory_summary: nul,
28835
+ browseUrls: { type: ["array", "null"], items: { type: "string" } },
28836
+ browseQuery: { type: ["string", "null"] }
28837
+ }),
28838
+ decisionBranch(["ask_user"], { clarifying_question: { type: "string" }, advisory_summary: nul, browseUrls: nul, browseQuery: nul }),
28839
+ decisionBranch(["advisory_response"], {
28840
+ clarifying_question: nul,
28841
+ advisory_summary: { type: ["string", "null"] },
28842
+ browseUrls: nul,
28843
+ browseQuery: nul
28844
+ }),
28845
+ decisionBranch(otherActions, { clarifying_question: nul, advisory_summary: nul, browseUrls: nul, browseQuery: nul })
28846
+ ]
28847
+ };
28848
+ }
28816
28849
  var LOCAL_GEMMA_DECISION_JSON_SCHEMA = buildLocalGemmaDecisionJsonSchema();
28817
28850
  var LOCAL_GEMMA_MAX_USER_PROMPT_CHARS = 4e3, LOCAL_GEMMA_MAX_CLARIFICATIONS = 4, LOCAL_GEMMA_MAX_CLARIFICATION_QUESTION_CHARS = 300, LOCAL_GEMMA_MAX_CLARIFICATION_ANSWER_CHARS = 900, LOCAL_GEMMA_MAX_CANONICAL_CONTEXT_CHARS = 6e3, LOCAL_GEMMA_MAX_RENDERED_PROMPT_CHARS = 24e3;
28818
28851
  function truncatePlannerTextPreservingEnds(text2, maxChars) {
@@ -29170,7 +29203,7 @@ function parseLocalGemmaPlannerDecision(raw) {
29170
29203
  throw validationError("Gemma planner browse output must not include advisory_summary or clarifying_question", obj, canDegrade);
29171
29204
  } else {
29172
29205
  let hasRealBrowseUrls = Array.isArray(obj.browseUrls) && obj.browseUrls.some(isRealHttpUrl), hasRealBrowseQuery = typeof obj.browseQuery == "string" && obj.browseQuery.trim().length > 0, userFacingPlannerText = typeof obj.advisory_summary == "string" && obj.advisory_summary.trim().length > 0 || typeof obj.clarifying_question == "string" && obj.clarifying_question.trim().length > 0, taskStartingAction = obj.action === "start_task" || obj.action === "team_decompose";
29173
- if ((hasRealBrowseUrls || hasRealBrowseQuery) && (userFacingPlannerText || taskStartingAction || obj.action === "refuse" || obj.action === "ask_user"))
29206
+ if ((hasRealBrowseUrls || hasRealBrowseQuery) && (userFacingPlannerText || taskStartingAction || obj.action === "advisory_response" && hasRealBrowseQuery || obj.action === "refuse" || obj.action === "ask_user"))
29174
29207
  throw new PlannerOutputUnparseableError(
29175
29208
  "Gemma planner non-browse output must not combine browse fields with user-facing or task-starting planner output",
29176
29209
  { kind: "validation" }
@@ -77317,7 +77350,7 @@ function OrchestrationApp(props) {
77317
77350
  setLiveRuntimeKind(kind), setLiveRuntimeLabel(props.plannerLabel ?? "");
77318
77351
  });
77319
77352
  }, [props.plannerPipeline, props.plannerLabel]);
77320
- let [syncDisplay, setSyncDisplay] = React22.useState(null), syncDisplayRef = React22.useRef(syncDisplay), syncOwner = state.session.userId;
77353
+ let [syncDisplay, setSyncDisplay] = React22.useState(null), [syncBootstrapSettledFor, setSyncBootstrapSettledFor] = React22.useState(null), syncDisplayRef = React22.useRef(syncDisplay), syncOwner = state.session.userId;
77321
77354
  React22.useEffect(() => {
77322
77355
  let source2 = props.companionSyncStateSource;
77323
77356
  if (!source2) return;
@@ -77325,16 +77358,19 @@ function OrchestrationApp(props) {
77325
77358
  if (!active) return;
77326
77359
  clearTimeout(expiry);
77327
77360
  let display = { userId: syncOwner, state: next };
77328
- syncDisplayRef.current = display, setSyncDisplay(display), next && (expiry = setTimeout(() => update(null), Math.max(0, next.validUntilEpochMs - Date.now())), expiry.unref?.());
77361
+ syncDisplayRef.current = display, setSyncDisplay(display), next && (setSyncBootstrapSettledFor(syncOwner), expiry = setTimeout(() => update(null), Math.max(0, next.validUntilEpochMs - Date.now())), expiry.unref?.());
77329
77362
  };
77330
- update(null);
77363
+ setSyncBootstrapSettledFor(null), update(null);
77331
77364
  try {
77332
77365
  unsubscribe = source2.subscribeCompanionSyncState(syncOwner, update);
77333
77366
  } catch {
77367
+ active && setSyncBootstrapSettledFor(syncOwner);
77334
77368
  }
77335
77369
  let deadline = setTimeout(() => abort.abort(), 4500);
77336
77370
  return deadline.unref?.(), Promise.resolve().then(() => source2.getCompanionSyncState(abort.signal)).catch(() => {
77337
- }).finally(() => clearTimeout(deadline)), () => {
77371
+ }).finally(() => {
77372
+ clearTimeout(deadline), active && setSyncBootstrapSettledFor(syncOwner);
77373
+ }), () => {
77338
77374
  active = !1, clearTimeout(expiry), clearTimeout(deadline), abort.abort(), unsubscribe?.();
77339
77375
  };
77340
77376
  }, [props.companionSyncStateSource, syncOwner]);
@@ -77613,7 +77649,7 @@ ${formatImplementorPolicy(detected, updated, props.tier)}`
77613
77649
  tier: props.tier,
77614
77650
  plannerRuntimeKind: liveRuntimeKind,
77615
77651
  plannerLabel: liveRuntimeLabel,
77616
- companionSyncBadge: props.companionSyncStateSource ? companionSyncBadge(syncDisplay?.userId === syncOwner ? syncDisplay.state : null) : null
77652
+ companionSyncBadge: props.companionSyncStateSource && (syncDisplay?.userId === syncOwner && syncDisplay.state || syncBootstrapSettledFor === syncOwner) ? companionSyncBadge(syncDisplay?.userId === syncOwner ? syncDisplay.state : null) : null
77617
77653
  }),
77618
77654
  // CP-12 W3 §3.5 — minimal multi-track status node, mounted ONLY when a team
77619
77655
  // is active. Single-track / Companion sessions leave `state.team`
@@ -83897,7 +83933,7 @@ var INTENT_CLASSIFIER_JSON_SCHEMA = {
83897
83933
  rationale: { type: "string" }
83898
83934
  },
83899
83935
  required: ["action", "is_code_or_disk_mutation", "confidence", "requires_file_read", "rationale"]
83900
- }, DEFAULT_INTENT_TIMEOUT_MS = 5e3, INTENT_MAX_OUTPUT_TOKENS = 256;
83936
+ }, DEFAULT_INTENT_TIMEOUT_MS = 3e4, INTENT_MAX_OUTPUT_TOKENS = 256;
83901
83937
  function buildIntentClassifierPrompt(prompt, clarifications) {
83902
83938
  return [
83903
83939
  "You are a strict code/workspace intent classifier for CodeVibe.",
@@ -86714,7 +86750,7 @@ async function runOrchestrationShellSession(args) {
86714
86750
  { teardownDeadlineExpired: !0 }
86715
86751
  ) : void 0,
86716
86752
  start: () => {
86717
- shellSubmissionsFenced = !0, shellSyncRecovery.stop(), fenceHostedSessionIngress(), taskOrdinalsAtEarlyRelease = store.getState().taskOrdinals.size, earlySessionWorkRelease = releaseSessionWorkBeforeRetirement();
86753
+ shellSubmissionsFenced = !0, activeBrowseAbortController?.abort(), shellSyncRecovery.stop(), fenceHostedSessionIngress(), taskOrdinalsAtEarlyRelease = store.getState().taskOrdinals.size, earlySessionWorkRelease = releaseSessionWorkBeforeRetirement();
86718
86754
  let splitLocalDurableRetirement = typeof args.localExecutor?.disposeDurableSessionResources == "function", workspaceShutdown = startWorkspaceShutdownOperations({
86719
86755
  ...args.plannerAdapter || args.localAdvisoryRunner ? {
86720
86756
  clearPlannerSession: () => {
@@ -91342,6 +91378,13 @@ async function handleShellUserInput(deps) {
91342
91378
  } finally {
91343
91379
  stopClassifyRelabel?.();
91344
91380
  }
91381
+ if (browseSignal?.aborted) {
91382
+ logger.info(
91383
+ "[orchestration-shell] Planner classify turn aborted via browseSignal; returning silently",
91384
+ { prompt: plannerInput.prompt }
91385
+ ), clearPendingClarificationIfPresent(store);
91386
+ return;
91387
+ }
91345
91388
  logger.info("[orchestration-shell] Planner classified input", {
91346
91389
  prompt: plannerInput.prompt,
91347
91390
  action: decision.action,
@@ -91354,8 +91397,16 @@ async function handleShellUserInput(deps) {
91354
91397
  if ((decision.action === "start_task" || decision.action === "browse") && args.localAdvisoryRunner && process.env.CODEVIBE_INTENT_CLASSIFIER !== "regex") {
91355
91398
  let gemmaIntent = await classifyPromptIntentWithGemma(
91356
91399
  { prompt: plannerInput.prompt, clarifications: plannerInput.clarifications },
91357
- args.localAdvisoryRunner
91400
+ args.localAdvisoryRunner,
91401
+ ...browseSignal ? [{ signal: browseSignal }] : []
91358
91402
  );
91403
+ if (browseSignal?.aborted) {
91404
+ logger.info(
91405
+ "[orchestration-shell] Gemma intent classifier aborted via browseSignal; returning silently",
91406
+ { prompt: plannerInput.prompt, rationale: gemmaIntent.rationale }
91407
+ ), clearPendingClarificationIfPresent(store);
91408
+ return;
91409
+ }
91359
91410
  if (gemmaIntent.source === "model")
91360
91411
  gemmaEvaluatedIntent = !0, decision.action === "browse" ? gemmaIntent.is_code_or_disk_mutation && (logger.info(
91361
91412
  "[orchestration-shell] Gemma intent classifier: promoting browse to start_task with code/disk mutation",
@@ -91372,6 +91423,12 @@ async function handleShellUserInput(deps) {
91372
91423
  ), decision = {
91373
91424
  action: "familiarize",
91374
91425
  rationale: decision.rationale ? `${decision.rationale} (demoted to familiarize via Gemma intent classifier)` : gemmaIntent.rationale
91426
+ }) : gemmaIntent.action === "browse" && !gemmaIntent.requires_file_read ? (logger.info(
91427
+ "[orchestration-shell] Gemma intent classifier: demoting start_task to browse",
91428
+ { prompt: plannerInput.prompt, rationale: gemmaIntent.rationale }
91429
+ ), decision = {
91430
+ action: "browse",
91431
+ rationale: decision.rationale ? `${decision.rationale} (demoted to browse via Gemma intent classifier)` : gemmaIntent.rationale
91375
91432
  }) : (logger.info(
91376
91433
  "[orchestration-shell] Gemma intent classifier: demoting start_task to advisory_response",
91377
91434
  { prompt: plannerInput.prompt, rationale: gemmaIntent.rationale }
@@ -20,6 +20,7 @@ export interface GemmaIntentPort {
20
20
  }>;
21
21
  }
22
22
  export declare const INTENT_CLASSIFIER_JSON_SCHEMA: Record<string, unknown>;
23
+ export declare const DEFAULT_INTENT_TIMEOUT_MS = 30000;
23
24
  export declare function buildIntentClassifierPrompt(prompt: string, clarifications?: {
24
25
  question: string;
25
26
  answer: string;
@@ -67,35 +67,44 @@ export declare class PlannerOutputUnparseableError extends Error {
67
67
  });
68
68
  }
69
69
  export declare function localGemmaAllowedActions(): ReadonlySet<PlannerDecision['action']>;
70
- interface LocalGemmaDecisionJsonSchema {
70
+ type NullField = {
71
+ type: 'null';
72
+ };
73
+ type StringField = {
74
+ type: 'string';
75
+ };
76
+ type NullableStringField = {
77
+ type: ['string', 'null'];
78
+ };
79
+ type NullableUrlsField = {
80
+ type: ['array', 'null'];
81
+ items: {
82
+ type: 'string';
83
+ };
84
+ };
85
+ /** One per-action branch of the planner decision schema (planner parity D-15). */
86
+ export interface LocalGemmaDecisionBranchSchema {
71
87
  type: 'object';
72
88
  properties: {
73
- rationale: {
74
- type: 'string';
75
- };
76
- clarifying_question: {
77
- type: ['string', 'null'];
78
- };
79
- advisory_summary: {
80
- type: ['string', 'null'];
81
- };
82
- browseUrls: {
83
- type: ['array', 'null'];
84
- items: {
85
- type: 'string';
86
- };
87
- };
88
- browseQuery: {
89
- type: ['string', 'null'];
90
- };
89
+ rationale: StringField;
90
+ clarifying_question: StringField | NullableStringField | NullField;
91
+ advisory_summary: NullableStringField | NullField;
92
+ browseUrls: NullableUrlsField | NullField;
93
+ browseQuery: NullableStringField | NullField;
91
94
  action: {
92
95
  type: 'string';
93
96
  enum: PlannerDecision['action'][];
94
97
  };
95
98
  };
96
99
  required: string[];
97
- additionalProperties: boolean;
100
+ additionalProperties: false;
101
+ }
102
+ /** The planner decision schema: exactly one branch per action family (planner parity D-15). */
103
+ export interface LocalGemmaDecisionJsonSchema {
104
+ anyOf: LocalGemmaDecisionBranchSchema[];
98
105
  }
106
+ /** Every action the decision schema can emit, in branch order (each exactly once). */
107
+ export declare function localGemmaDecisionSchemaActions(schema?: LocalGemmaDecisionJsonSchema): PlannerDecision['action'][];
99
108
  /**
100
109
  * The ONE planner decision schema (both runtimes). Its canonical SHA-256 is allow-listed by
101
110
  * planner-proxy (`lambda/planner-proxy/schemas.ts`); a change here needs the backend
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-core",
3
- "version": "2.0.88",
3
+ "version": "2.0.89",
4
4
  "description": "Core library for CodeVibe plugins - shared keychain, crypto, AppSync, and auth functionality",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",