@quantiya/codevibe-claude-plugin 2.0.73 → 2.0.74

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.
Files changed (32) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/node_modules/@quantiya/codevibe-core/dist/appsync/appsync-client.d.ts +39 -0
  3. package/node_modules/@quantiya/codevibe-core/dist/appsync/queries.d.ts +2 -0
  4. package/node_modules/@quantiya/codevibe-core/dist/index.d.ts +1 -1
  5. package/node_modules/@quantiya/codevibe-core/dist/index.js +564 -552
  6. package/node_modules/@quantiya/codevibe-core/dist/local-model/ollama-gemma-runner.d.ts +18 -0
  7. package/node_modules/@quantiya/codevibe-core/dist/local-model/ollama.d.ts +26 -0
  8. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/attachments.d.ts +8 -14
  9. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.d.ts +49 -63
  10. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.js +2395 -2407
  11. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/components/OrchestrationApp.d.ts +3 -1
  12. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/git-status-summary.d.ts +5 -10
  13. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/index.d.ts +29 -46
  14. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/route-browse.d.ts +4 -4
  15. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/runtime-labels.d.ts +63 -0
  16. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/task-progress-relay.d.ts +9 -1
  17. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/task-progress.d.ts +7 -0
  18. package/node_modules/@quantiya/codevibe-core/dist/planner/cache.d.ts +7 -0
  19. package/node_modules/@quantiya/codevibe-core/dist/planner/gemma-errors.d.ts +61 -0
  20. package/node_modules/@quantiya/codevibe-core/dist/planner/gemma-pipeline.d.ts +219 -0
  21. package/node_modules/@quantiya/codevibe-core/dist/planner/gemma-runner.d.ts +66 -0
  22. package/node_modules/@quantiya/codevibe-core/dist/planner/hosted-gemma-runner.d.ts +83 -0
  23. package/node_modules/@quantiya/codevibe-core/dist/planner/index.d.ts +5 -3
  24. package/node_modules/@quantiya/codevibe-core/dist/planner/local-advisory.d.ts +3 -6
  25. package/node_modules/@quantiya/codevibe-core/dist/planner/local-gemma.d.ts +82 -21
  26. package/node_modules/@quantiya/codevibe-core/dist/planner/types.d.ts +4 -4
  27. package/node_modules/@quantiya/codevibe-core/dist/reviewer/verdict-classifier.d.ts +18 -5
  28. package/node_modules/@quantiya/codevibe-core/package.json +1 -1
  29. package/package.json +2 -2
  30. package/node_modules/@quantiya/codevibe-core/dist/planner/composite-adapter.d.ts +0 -39
  31. package/node_modules/@quantiya/codevibe-core/dist/planner/composite-advisory.d.ts +0 -26
  32. package/node_modules/@quantiya/codevibe-core/dist/planner/hosted-advisory.d.ts +0 -40
@@ -0,0 +1,66 @@
1
+ import type { GemmaRuntime } from './gemma-errors';
2
+ export type ImageFormat = 'png' | 'jpeg' | 'gif' | 'bmp' | 'webp';
3
+ export interface RunnerImageCapability {
4
+ maxCount: number;
5
+ /** Sum of raw image bytes per call. */
6
+ maxTotalRawBytes: number;
7
+ maxImageRawBytes: number;
8
+ formats: readonly ImageFormat[];
9
+ /**
10
+ * Hosted only (§3.3): the exact serialized provider body must not exceed this, so a
11
+ * JSON-escaping-heavy prompt leaves room for fewer images.
12
+ */
13
+ maxProviderBodyBytes?: number;
14
+ /** Hosted only: the AppSync/Lambda leg's total ciphertext ceiling (planner-proxy, unchanged). */
15
+ maxTotalCiphertextBytes?: number;
16
+ }
17
+ export interface RunnerCapabilities {
18
+ images: RunnerImageCapability;
19
+ }
20
+ export interface RunnerResult {
21
+ text: string;
22
+ finishReason: 'stop' | 'length';
23
+ }
24
+ export interface RunnerClassifyOptions {
25
+ /** Absent → JSON-object mode (Ollama `format:"json"`, Mantle `json_object`). */
26
+ jsonSchema?: object;
27
+ maxOutputTokens: number;
28
+ timeoutMs?: number;
29
+ signal?: AbortSignal;
30
+ }
31
+ export interface RunnerImage {
32
+ /** Raw base64, no `data:` prefix. */
33
+ base64: string;
34
+ format: ImageFormat;
35
+ rawBytes: number;
36
+ }
37
+ export interface RunnerAdvisoryOptions {
38
+ responseFormat: 'json' | 'text';
39
+ maxOutputTokens: number;
40
+ /** Already selected for THIS runner by the pipeline (§3.7). */
41
+ images: RunnerImage[];
42
+ timeoutMs?: number;
43
+ signal?: AbortSignal;
44
+ /** Ollama transport knobs (§3.3); hosted ignores them. */
45
+ numCtx?: number;
46
+ think?: boolean;
47
+ }
48
+ export interface GemmaRunner {
49
+ readonly runtime: GemmaRuntime;
50
+ /** Display only: never read for behaviour. */
51
+ readonly label: string;
52
+ readonly capabilities: RunnerCapabilities;
53
+ classify(prompt: string, opts: RunnerClassifyOptions): Promise<RunnerResult>;
54
+ generateAdvisory(prompt: string, opts: RunnerAdvisoryOptions): Promise<RunnerResult>;
55
+ /** Liveness probe for the composite's recovery timer; never throws. */
56
+ probe(): Promise<boolean>;
57
+ /** Session binding (hosted needs the active session and its key; local ignores it). */
58
+ setActiveSession?(sessionId: string | null): void;
59
+ /** Fire-and-forget model pre-warm / release (local only); never throw. */
60
+ warm?(): Promise<boolean>;
61
+ unload?(): Promise<boolean>;
62
+ }
63
+ export declare const LOCAL_IMAGE_CAPABILITY: RunnerImageCapability;
64
+ export declare const HOSTED_IMAGE_CAPABILITY: RunnerImageCapability;
65
+ export declare function imageFormatFromMime(mime: string): ImageFormat | null;
66
+ export declare function mimeFromImageFormat(format: ImageFormat): string;
@@ -0,0 +1,83 @@
1
+ import { GemmaCallError } from './gemma-errors';
2
+ import { type GemmaRunner, type RunnerAdvisoryOptions, type RunnerCapabilities, type RunnerClassifyOptions, type RunnerImage, type RunnerResult } from './gemma-runner';
3
+ export interface HostedRenderedTransport {
4
+ classifyRenderedPlannerPrompt(input: {
5
+ sessionId: string;
6
+ encryptedPrompt: string;
7
+ responseSchema?: string;
8
+ maxOutputTokens: number;
9
+ }, signal?: AbortSignal): Promise<{
10
+ encryptedOutput: string;
11
+ finishReason: 'STOP' | 'LENGTH' | null;
12
+ }>;
13
+ generatePlannerAdvisoryRendered(input: {
14
+ sessionId: string;
15
+ prompt: string;
16
+ images?: string[];
17
+ maxTokens: number;
18
+ temperature: number;
19
+ responseFormat: 'TEXT' | 'JSON_OBJECT';
20
+ }, signal?: AbortSignal): Promise<{
21
+ advisoryText: string;
22
+ finishReason: 'STOP' | 'LENGTH' | null;
23
+ }>;
24
+ }
25
+ export interface HostedRunnerCrypto {
26
+ encryptString(plaintext: string, sessionKeyB64: string): string;
27
+ decryptString(ciphertextB64: string, sessionKeyB64: string): string;
28
+ }
29
+ export interface HostedSessionKeyResolver {
30
+ getSessionKey(sessionId: string): Promise<string | null>;
31
+ }
32
+ /**
33
+ * The model id the server's body uses (planner-proxy `DEFAULT_BEDROCK_MODEL_ID`). The client's
34
+ * 3,400,000 B body limit sits 100 KB under the server's 3,500,000 B check, which absorbs any
35
+ * difference in the model id the server is configured with.
36
+ */
37
+ export declare const HOSTED_BODY_MODEL_ID = "google.gemma-4-26b-a4b";
38
+ /**
39
+ * Mirror of planner-proxy `renderedChatBody` + `invokeMantle` (§4.2): the exact JSON body the
40
+ * server sends for a client-rendered call, so the pipeline can select images against the
41
+ * provider-body limit BEFORE sending (§3.3, §3.4 step 5). Field order is part of the contract;
42
+ * a cross-repo golden fixture pins it on both sides.
43
+ */
44
+ export declare function hostedRenderedBody(req: {
45
+ promptText: string;
46
+ images?: Array<{
47
+ mime: string;
48
+ base64: string;
49
+ }>;
50
+ maxOutputTokens: number;
51
+ temperature: number;
52
+ responseFormat?: unknown;
53
+ }): string;
54
+ export declare function hostedRenderedBodyBytes(req: Parameters<typeof hostedRenderedBody>[0]): number;
55
+ /** base64(AES-GCM(utf-8 plaintext)) length for a plaintext of `plaintextBytes` (nonce 12 + tag 16). */
56
+ export declare function sessionCiphertextLength(plaintextBytes: number): number;
57
+ /** Map any failure of a hosted call to the typed set (§3.2). Reads the server's verbatim message. */
58
+ export declare function toHostedGemmaError(err: unknown, signal?: AbortSignal): GemmaCallError;
59
+ export declare class HostedGemmaRunner implements GemmaRunner {
60
+ private readonly deps;
61
+ readonly runtime: "hosted";
62
+ readonly label = "Hosted Gemma (AWS Bedrock)";
63
+ readonly capabilities: RunnerCapabilities;
64
+ private activeSessionId;
65
+ constructor(deps: {
66
+ transport: HostedRenderedTransport;
67
+ crypto: HostedRunnerCrypto;
68
+ sessionKeyResolver: HostedSessionKeyResolver;
69
+ });
70
+ setActiveSession(sessionId: string | null): void;
71
+ private sessionAndKey;
72
+ private finish;
73
+ private withTimeout;
74
+ classify(prompt: string, opts: RunnerClassifyOptions): Promise<RunnerResult>;
75
+ generateAdvisory(prompt: string, opts: RunnerAdvisoryOptions): Promise<RunnerResult>;
76
+ /** Hosted is the composite's fallback; it is never probed for recovery. */
77
+ probe(): Promise<boolean>;
78
+ }
79
+ /** Data-URI image parts as the server will build them (for the body-size mirror). */
80
+ export declare function hostedBodyImages(images: RunnerImage[]): Array<{
81
+ mime: string;
82
+ base64: string;
83
+ }>;
@@ -5,6 +5,8 @@ export { PlannerHealthMachine } from './health-state';
5
5
  export { BackendPlannerClient, PlannerBudgetExceededError, PlannerTierGateRejectedError, type PlannerAppSyncTransport, type PlannerCryptoBridge, type SessionKeyResolver, type ShellEventEmit, type EmitShellEventFn, } from './client';
6
6
  export { LocalGemmaPlannerAdapter, parseLocalGemmaPlannerDecision, PlannerOutputUnparseableError, renderLocalGemmaPlannerPrompt, type LocalGemmaPlannerRunner, } from './local-gemma';
7
7
  export { parseLocalGemmaAdvisorySummary, renderLocalGemmaFamiliarizePrompt, renderLocalGemmaMultiBrowsePrompt, renderLocalGemmaBrowsePrompt, MAX_BROWSE_CONTENT_CHARS, MAX_MULTI_BROWSE_TOTAL_CONTENT_CHARS, MAX_MULTI_BROWSE_RENDERED_PROMPT_CHARS, type AdvisoryRunner, type AdvisoryOptions, type AdvisoryResponseFormat, type LocalGemmaAdvisoryRunner, type LocalGemmaAdvisoryOptions, type LocalGemmaAdvisoryResponseFormat, } from './local-advisory';
8
- export { CompositePlannerAdapter, type CompositePlannerAdapterOptions, } from './composite-adapter';
9
- export { HostedGemmaAdvisoryRunner, type HostedGemmaAdvisoryRunnerDeps, type HostedAdvisoryTransport, } from './hosted-advisory';
10
- export { CompositeAdvisoryRunner, type CompositeAdvisoryRunnerOptions, } from './composite-advisory';
8
+ export { GemmaPlannerAdapter, applyMaxTierGate, renderGemmaPlannerPrompt, parseGemmaPlannerDecision, type GemmaClassifyPort, } from './local-gemma';
9
+ export * from './gemma-errors';
10
+ export * from './gemma-runner';
11
+ export * from './gemma-pipeline';
12
+ export * from './hosted-gemma-runner';
@@ -13,7 +13,6 @@ export interface AdvisoryRunner {
13
13
  */
14
14
  unload?(): Promise<boolean>;
15
15
  runtimeLabel: string;
16
- readonly providerKind?: 'local' | 'hosted';
17
16
  }
18
17
  export type AdvisoryResponseFormat = 'json' | 'text';
19
18
  export interface AdvisoryOptions {
@@ -21,11 +20,9 @@ export interface AdvisoryOptions {
21
20
  numPredict?: number;
22
21
  /**
23
22
  * RAW base64 images (NO `data:` prefix) for the MULTIMODAL local answerer
24
- * (IMAGE-ATTACHMENT-DESIGN.md §6). Set ONLY by the shell's `routeAdvisory` /
25
- * image-brainstorm with `responseFormat:'text'`. The Ollama runtime forwards
26
- * these to `/api/generate images[]`; the subprocess `LocalGemmaProcessRunner`
27
- * has no image channel and IGNORES them (documented no-op, §6 Role B). NEVER set
28
- * on the classifier (forced-JSON) or on `browse`/`familiarize`.
23
+ * (IMAGE-ATTACHMENT-DESIGN.md §6) on this legacy runner shape. The Ollama runtime
24
+ * forwards these to `/api/generate images[]`. The orchestration shell's image
25
+ * callers go through the Gemma pipeline's `advise()` (planner parity §3.7).
29
26
  */
30
27
  images?: string[];
31
28
  /**
@@ -21,7 +21,6 @@ export interface LocalGemmaPlannerRunner {
21
21
  */
22
22
  unload?(): Promise<boolean>;
23
23
  runtimeLabel: string;
24
- readonly providerKind?: 'local' | 'hosted';
25
24
  }
26
25
  /**
27
26
  * A1a P0 (R3 — design §7 "the conductor must NEVER hard-fail"): thrown when the
@@ -67,7 +66,7 @@ export declare class PlannerOutputUnparseableError extends Error {
67
66
  degradeTo?: PlannerOutputUnparseableError['degradeTo'];
68
67
  });
69
68
  }
70
- export declare function localGemmaAllowedActions(isSubprocessRunner: boolean): ReadonlySet<PlannerDecision['action']>;
69
+ export declare function localGemmaAllowedActions(): ReadonlySet<PlannerDecision['action']>;
71
70
  interface LocalGemmaDecisionJsonSchema {
72
71
  type: 'object';
73
72
  properties: {
@@ -75,19 +74,19 @@ interface LocalGemmaDecisionJsonSchema {
75
74
  type: 'string';
76
75
  };
77
76
  clarifying_question: {
78
- type: 'string';
77
+ type: ['string', 'null'];
79
78
  };
80
79
  advisory_summary: {
81
- type: 'string';
80
+ type: ['string', 'null'];
82
81
  };
83
82
  browseUrls: {
84
- type: 'array';
83
+ type: ['array', 'null'];
85
84
  items: {
86
85
  type: 'string';
87
86
  };
88
87
  };
89
88
  browseQuery: {
90
- type: 'string';
89
+ type: ['string', 'null'];
91
90
  };
92
91
  action: {
93
92
  type: 'string';
@@ -97,30 +96,92 @@ interface LocalGemmaDecisionJsonSchema {
97
96
  required: string[];
98
97
  additionalProperties: boolean;
99
98
  }
100
- /** The Ollama runner's schema (no `summarize_current_status`). */
99
+ /**
100
+ * The ONE planner decision schema (both runtimes). Its canonical SHA-256 is allow-listed by
101
+ * planner-proxy (`lambda/planner-proxy/schemas.ts`); a change here needs the backend
102
+ * allow-list updated first (design §4.1, §10) or hosted decoding degrades to JSON-object mode.
103
+ */
101
104
  export declare const LOCAL_GEMMA_DECISION_JSON_SCHEMA: LocalGemmaDecisionJsonSchema;
102
- /** The subprocess runner's schema keeps `summarize_current_status` (Stage-2 codex R1-F3). */
103
- export declare const LOCAL_GEMMA_SUBPROCESS_DECISION_JSON_SCHEMA: LocalGemmaDecisionJsonSchema;
105
+ export declare const GEMMA_DECISION_JSON_SCHEMA: LocalGemmaDecisionJsonSchema;
104
106
  /**
105
- * Text-only route classifier prompt. It intentionally excludes repository
106
- * paths, summaries, source snippets, file bodies, and the raw structural digest.
107
+ * The shape the planner prompt was rendered with — sizes and counts only, never text (Stage 2
108
+ * codex S2-codex-F4: the evidence that a maximum input reached the model as rendered).
107
109
  */
108
- export declare function renderLocalGemmaPlannerPrompt(input: PlannerInput, options?: {
109
- isSubprocessRunner?: boolean;
110
- }): string;
110
+ export interface PlannerPromptShape {
111
+ /**
112
+ * The input after the per-field caps (prompt 4,000; clarifications compacted to 4, questions
113
+ * 300 / answers 900; context 6,000) and BEFORE fitting to the rendered-prompt cap. A maximum
114
+ * input (the design's S9 shape) shows every field at its cap here.
115
+ */
116
+ capped: {
117
+ userPromptChars: number;
118
+ clarifications: number;
119
+ clarificationQuestionChars: number[];
120
+ clarificationAnswerChars: number[];
121
+ contextChars: number;
122
+ };
123
+ /** What was rendered after fitting (oldest clarifications go first, then context, then prompt). */
124
+ userPromptChars: number;
125
+ clarifications: number;
126
+ clarificationQuestionChars: number[];
127
+ clarificationAnswerChars: number[];
128
+ contextChars: number;
129
+ examplesKept: number;
130
+ renderedChars: number;
131
+ renderedBytes: number;
132
+ }
133
+ export declare function renderLocalGemmaPlannerPrompt(input: PlannerInput): string;
134
+ /** {@link renderLocalGemmaPlannerPrompt} plus the rendered shape (sizes and counts only). */
135
+ export declare function renderLocalGemmaPlannerPromptWithShape(input: PlannerInput): {
136
+ prompt: string;
137
+ shape: PlannerPromptShape;
138
+ };
111
139
  /** Characters of raw model output retained on {@link PlannerOutputUnparseableError.rawOutputHead}. */
112
140
  export declare const RAW_OUTPUT_HEAD_CHARS = 500;
113
141
  /** Terminal-control-free, bounded head of a raw model output for the warn log. */
114
142
  export declare function summarizeRawOutputForLog(raw: string): string;
115
- export declare function parseLocalGemmaPlannerDecision(raw: string, options?: {
116
- isSubprocessRunner?: boolean;
117
- }): PlannerDecision;
118
- export declare class LocalGemmaPlannerAdapter implements PlannerAdapter {
119
- private readonly runner;
120
- private activeSessionId;
121
- constructor(runner: LocalGemmaPlannerRunner);
143
+ export declare function parseLocalGemmaPlannerDecision(raw: string): PlannerDecision;
144
+ /**
145
+ * The adapter's view of the shared pipeline (`gemma-pipeline.ts`): a classify call that
146
+ * returns the raw model text. The adapter never sees which runtime answered (§3.2).
147
+ */
148
+ export interface GemmaClassifyPort {
149
+ classify(req: {
150
+ prompt: string;
151
+ jsonSchema?: object;
152
+ maxOutputTokens: number;
153
+ }): Promise<{
154
+ text: string;
155
+ }>;
156
+ setActiveSession?(sessionId: string | null): void;
157
+ }
158
+ /**
159
+ * Planner parity D-4 (codevibe-backend docs/2.0/PLANNER-RUNTIME-PARITY-DESIGN.md §3.3): the
160
+ * Max-tier gate on `team_decompose`, on BOTH runtimes, exactly the server's former rule
161
+ * (planner-proxy `applyDeterministicMaxGate`). It runs post-parse, so a converted `start_task`
162
+ * still passes the shell's P43 destructive backstop and `confirmBeforeStart`.
163
+ */
164
+ export declare function applyMaxTierGate(decision: PlannerDecision, tier: PlannerInput['sessionContext']['tier']): PlannerDecision;
165
+ /**
166
+ * The ONE planner implementation for both runtimes (§3.1): render the shared prompt, classify
167
+ * through the pipeline (which owns failover and the runtime), parse with the shared parser,
168
+ * apply the Max gate. Identical logic whichever runtime answered.
169
+ */
170
+ export declare class GemmaPlannerAdapter implements PlannerAdapter {
171
+ private readonly port;
172
+ constructor(port: GemmaClassifyPort);
122
173
  classify(input: PlannerInput): Promise<PlannerDecision>;
123
174
  probe(): Promise<PlannerProbeResult>;
124
175
  setActiveSession(sessionId: string | null): void;
125
176
  }
177
+ /**
178
+ * Compatibility alias (§3.1: "the old name stays as an alias"): wraps a legacy text runner
179
+ * (`classify(prompt, { jsonSchema, numPredict }) → string`) as the classify port. Used by
180
+ * tests and spikes; production builds `GemmaPlannerAdapter` over the pipeline.
181
+ */
182
+ export declare class LocalGemmaPlannerAdapter extends GemmaPlannerAdapter {
183
+ constructor(runner: LocalGemmaPlannerRunner);
184
+ }
185
+ export declare const renderGemmaPlannerPrompt: typeof renderLocalGemmaPlannerPrompt;
186
+ export declare const parseGemmaPlannerDecision: typeof parseLocalGemmaPlannerDecision;
126
187
  export {};
@@ -64,10 +64,10 @@ export interface PlannerInput {
64
64
  sessionContext: SessionContext;
65
65
  budgetHint: BudgetHint;
66
66
  /**
67
- * Local-planner-only, role-filtered rendering of the canonical ContextItems
68
- * session history. The hosted planner client deliberately ignores this field;
69
- * it exists so local Gemma can resolve ordinary multi-turn references without
70
- * relying on shell text heuristics or a model-private conversation cache.
67
+ * Role-filtered rendering of the canonical ContextItems session history, given to
68
+ * the planner on BOTH runtimes (planner parity D-2: one rendered prompt for local and
69
+ * hosted). It lets the planner resolve ordinary multi-turn references without relying
70
+ * on shell text heuristics or a model-private conversation cache.
71
71
  */
72
72
  canonicalConversationContext?: string;
73
73
  }
@@ -1,4 +1,3 @@
1
- import type { LocalGemmaPlannerRunner } from '../planner/local-gemma';
2
1
  import type { AgentKind, ReviewerRole, VerdictKind } from './types';
3
2
  /** Per-verdict context (seat/role/agent) — carried for observability; the Gemma
4
3
  * classification itself is context-free (deterministic on `rawText`). */
@@ -22,6 +21,20 @@ export type VerdictClassifier = (rawText: string, ctx: VerdictClassifierContext)
22
21
  export declare const VERDICT_CLASSIFIER_UNCERTAIN = "verdict_classifier_uncertain";
23
22
  export declare const VERDICT_CLASSIFIER_CONFLICT = "verdict_classifier_conflict";
24
23
  export declare const VERDICT_CLASSIFIER_UNAVAILABLE = "verdict_classifier_unavailable";
24
+ /**
25
+ * The slice of `GemmaCallPipeline` the classifier uses (structural, so tests inject a
26
+ * fake). Absent `jsonSchema` → JSON-object mode on both runtimes.
27
+ */
28
+ export interface VerdictGemmaPort {
29
+ classify(req: {
30
+ prompt: string;
31
+ maxOutputTokens: number;
32
+ signal?: AbortSignal;
33
+ }): Promise<{
34
+ text: string;
35
+ }>;
36
+ runOutsideTurn<T>(fn: () => Promise<T>): Promise<T>;
37
+ }
25
38
  /**
26
39
  * Build a fail-closed Gemma verdict classifier. Order:
27
40
  * (1) empty `rawText.trim()===''` → ESCALATE (no `classify` call);
@@ -33,14 +46,14 @@ export declare const VERDICT_CLASSIFIER_UNAVAILABLE = "verdict_classifier_unavai
33
46
  * A genuine non-ESCALATE verdict (and a genuine reviewer ESCALATE) returns NO
34
47
  * `reason` so the provider keeps the reviewer's own reasoning.
35
48
  */
36
- export declare function makeGemmaVerdictClassifier(runner: LocalGemmaPlannerRunner, opts?: {
49
+ export declare function makeGemmaVerdictClassifier(port: VerdictGemmaPort, opts?: {
37
50
  timeoutMs?: number;
38
51
  }): VerdictClassifier;
39
52
  /**
40
53
  * A trivial classifier that returns ESCALATE (with a closed `reason` label) for
41
- * every input, with no runner. Installed by the wiring when flag=`gemma` but the
42
- * Gemma runner is null at boot (Ollama unreachable) — so `gemma` mode NEVER
43
- * silently degrades to the regex parser (agy-MED-1).
54
+ * every input, with no model call. Installed by the wiring when flag=`gemma` but the
55
+ * session has no Gemma source at boot — so `gemma` mode NEVER silently degrades to
56
+ * the regex parser (agy-MED-1).
44
57
  */
45
58
  export declare function alwaysEscalateClassifier(reason: string): VerdictClassifier;
46
59
  /**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-core",
3
- "version": "2.0.68",
3
+ "version": "2.0.69",
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-claude-plugin",
3
- "version": "2.0.73",
3
+ "version": "2.0.74",
4
4
  "description": "Control Claude Code from your iPhone and Android — real-time sync, approve file edits, send prompts by voice. Part of CodeVibe.",
5
5
  "main": "dist/server.js",
6
6
  "codevibe": {
@@ -48,7 +48,7 @@
48
48
  "node": ">=22.0.0"
49
49
  },
50
50
  "dependencies": {
51
- "@quantiya/codevibe-core": "^2.0.68",
51
+ "@quantiya/codevibe-core": "^2.0.69",
52
52
  "@quantiya/quorum-core": "^1.0.1",
53
53
  "dotenv": "^16.6.1",
54
54
  "express": "^5.1.0",
@@ -1,39 +0,0 @@
1
- import type { Tier } from '../orchestration-shell/types';
2
- import type { PlannerAdapter, PlannerDecision, PlannerInput, PlannerProbeResult } from './adapter';
3
- import type { PlannerHealthMachine } from './health-state';
4
- export interface CompositePlannerAdapterOptions {
5
- localAdapter?: PlannerAdapter | null;
6
- hostedAdapter: PlannerAdapter;
7
- tier: Tier;
8
- localRuntimeKind?: 'hosted' | 'local_gemma_qat' | 'local_unavailable';
9
- localRuntimeLabel?: string;
10
- hostedHealth?: PlannerHealthMachine | null;
11
- recoveryProbeIntervalMs?: number;
12
- onNotice?: (message: string) => void;
13
- onBeforeHostedFallback?: (input: PlannerInput) => Promise<PlannerInput>;
14
- }
15
- export declare class CompositePlannerAdapter implements PlannerAdapter {
16
- private readonly opts;
17
- private activeSessionId;
18
- private currentSource;
19
- private recoveryTimer;
20
- private readonly sourceChangeListeners;
21
- private readonly recoveryIntervalMs;
22
- private beforeHostedFallbackHook;
23
- constructor(opts: CompositePlannerAdapterOptions);
24
- setBeforeHostedFallback(hook: (input: PlannerInput) => Promise<PlannerInput>): void;
25
- get activeSource(): 'local' | 'hosted';
26
- get runtimeKind(): 'local_gemma_qat' | 'local_unavailable' | 'hosted';
27
- get runtimeLabel(): string;
28
- get suppressStructuralContextRefresh(): boolean;
29
- onSourceChange(listener: (source: 'local' | 'hosted') => void): () => void;
30
- private notifySourceChange;
31
- private transitionToHosted;
32
- private transitionToLocal;
33
- private startRecoveryProbe;
34
- private stopRecoveryProbe;
35
- setActiveSession(sessionId: string | null): void;
36
- classify(input: PlannerInput): Promise<PlannerDecision>;
37
- probe(): Promise<PlannerProbeResult>;
38
- dispose(): void;
39
- }
@@ -1,26 +0,0 @@
1
- import type { Tier } from '../orchestration-shell/types';
2
- import type { AdvisoryOptions, AdvisoryRunner } from './local-advisory';
3
- export interface CompositeAdvisoryRunnerOptions {
4
- localRunner?: AdvisoryRunner | null;
5
- hostedRunner: AdvisoryRunner;
6
- tier: Tier;
7
- onNotice?: (message: string) => void;
8
- onFallbackToHosted?: (error: Error) => void;
9
- }
10
- /**
11
- * CompositeAdvisoryRunner coordinates local and hosted advisory execution:
12
- * - Free Tier Invariant: strictly isolates Free tier from cloud inference ($0 marginal cost).
13
- * - Local-First Preference: routes natural language turns / browse to local Gemma when healthy.
14
- * - Dynamic Failover: if local Gemma fails (Ollama down, crash, OOM), seamlessly falls back
15
- * to hosted Bedrock Gemma for Pro/Max users without interrupting the session.
16
- */
17
- export declare class CompositeAdvisoryRunner implements AdvisoryRunner {
18
- private readonly opts;
19
- private localHealthy;
20
- constructor(opts: CompositeAdvisoryRunnerOptions);
21
- get runtimeLabel(): string;
22
- get providerKind(): 'local' | 'hosted';
23
- generateAdvisory(promptText: string, options?: AdvisoryOptions): Promise<string>;
24
- warm(): Promise<boolean>;
25
- unload(): Promise<boolean>;
26
- }
@@ -1,40 +0,0 @@
1
- import type { AdvisoryOptions, AdvisoryRunner } from './local-advisory';
2
- import type { PlannerCryptoBridge, SessionKeyResolver } from './client';
3
- export interface HostedAdvisoryTransport {
4
- generatePlannerAdvisory(input: {
5
- sessionId: string;
6
- prompt: string;
7
- images?: string[];
8
- maxTokens?: number;
9
- temperature?: number;
10
- }): Promise<{
11
- advisoryText: string;
12
- serverLatencyMs: number;
13
- providerUsed: string;
14
- }>;
15
- }
16
- export interface HostedGemmaAdvisoryRunnerDeps {
17
- transport: HostedAdvisoryTransport;
18
- crypto: PlannerCryptoBridge;
19
- sessionKeyResolver: SessionKeyResolver;
20
- activeSessionIdHolder: {
21
- value: string | null;
22
- };
23
- }
24
- /**
25
- * HostedGemmaAdvisoryRunner executes advisory text generation (browse synthesis,
26
- * brainstorm, etc.) against Google Gemma 3 12B on AWS Bedrock via AppSync planner proxy.
27
- *
28
- * Wire payload is encrypted in transit under the session key via AES-256-GCM to
29
- * the planner proxy Lambda in us-east-1, and decrypted server-side for AWS Bedrock Gemma 3 12B.
30
- * Multimodal image attachments (options.images) are encrypted under the session key.
31
- */
32
- export declare class HostedGemmaAdvisoryRunner implements AdvisoryRunner {
33
- private readonly deps;
34
- readonly runtimeLabel = "Hosted Gemma (AWS Bedrock)";
35
- readonly providerKind: "hosted";
36
- constructor(deps: HostedGemmaAdvisoryRunnerDeps);
37
- generateAdvisory(promptText: string, options?: AdvisoryOptions): Promise<string>;
38
- warm(): Promise<boolean>;
39
- unload(): Promise<boolean>;
40
- }