You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by as...@apache.org on 2026/10/21 09:20:27 UTC
(maka) branch main updated: feat(minimax): refresh direct Flash catalog and thinking support (#5908)
This is an automated email from the ASF dual-hosted git repository.
Astro-Han pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/maka.git
The following commit(s) were added to refs/heads/main by this push:
new 76e5c4e6fd feat(minimax): refresh direct Flash catalog and thinking support (#5908)
76e5c4e6fd is described below
commit 76e5c4e6fda133dcfd4103a7c4c4f05864d4abd7
Author: Octopus <je...@gmail.com>
AuthorDate: Wed Oct 21 17:20:22 2026 +0800
feat(minimax): refresh direct Flash catalog and thinking support (#5908)
fix(core): enable MiniMax-M3 thinking toggle for both regions
Generated-by: Codex
Merge current upstream main into MiniMax rollout branch
Generated-by: Codex
feat(minimax): refresh direct Flash catalog and thinking support
Generated-by: Codex
---
packages/core/src/__tests__/model-catalog.test.ts | 36 +++++++++
.../core/src/__tests__/models-dev-refresh.test.ts | 18 +++++
packages/core/src/model-catalog.ts | 23 +++++-
packages/core/src/model-metadata.ts | 11 ++-
packages/core/src/models-dev-projection.ts | 43 ++++++++++-
packages/core/src/provider-registry.ts | 4 +-
.../src/__tests__/model-factory-thinking.test.ts | 85 ++++++++++++++++++++++
packages/runtime/src/model-factory.ts | 10 +++
packages/runtime/src/telemetry/builtin-pricing.ts | 27 ++++++-
scripts/sync-model-metadata.mjs | 6 ++
scripts/sync-model-metadata.test.mjs | 10 +++
11 files changed, 266 insertions(+), 7 deletions(-)
diff --git a/packages/core/src/__tests__/model-catalog.test.ts b/packages/core/src/__tests__/model-catalog.test.ts
index 36f52c826b..d0fcccb956 100644
--- a/packages/core/src/__tests__/model-catalog.test.ts
+++ b/packages/core/src/__tests__/model-catalog.test.ts
@@ -48,6 +48,42 @@ function verdict(input: BuildModelCatalogInput) {
return { ok: entry?.canUseAsChatDefault === true };
}
+test('MiniMax current catalog is Flash first while custom, saved and non-text models survive', () => {
+ for (const providerType of ['MiniMax', 'MiniMax-cn'] as const) {
+ for (const modelSource of ['fallback', 'fetched'] as const) {
+ const entries = buildModelCatalogEntries({
+ providerType,
+ modelSource,
+ models: [
+ { id: 'MiniMax-M2.7' },
+ { id: 'MiniMax-M3', contextWindow: 204800 },
+ { id: 'custom-text' },
+ { id: 'speech-02-hd', modalities: { input: ['text'], output: ['audio'] } },
+ ],
+ savedModelIds: ['MiniMax-M2.5'],
+ });
+ assert.deepEqual(
+ entries.map(({ id }) => id),
+ ['MiniMax-M3.1-Flash', 'MiniMax-M3', 'custom-text', 'speech-02-hd', 'MiniMax-M2.5'],
+ );
+ assert.equal(entries[0]?.contextWindow, 1_000_000);
+ assert.equal(entries[1]?.contextWindow, 1_000_000);
+ assert.deepEqual(entries[0]?.thinkingLevels, ['low', 'medium', 'high', 'xhigh', 'max']);
+ assert.deepEqual(entries[1]?.thinkingLevels, ['off', 'on']);
+ }
+ assert.equal(
+ buildModelCatalogEntries({ providerType, defaultModel: 'MiniMax-M2.7' })[0]?.id,
+ 'MiniMax-M2.7',
+ );
+ }
+ assert.deepEqual(
+ buildModelCatalogEntries({ providerType: 'custom', models: [{ id: 'MiniMax-M2.7' }] }).map(
+ ({ id }) => id,
+ ),
+ ['MiniMax-M2.7'],
+ );
+});
+
test('catalog transport preserves independent limits and their unmodified defaults', () => {
const [entry] = buildModelCatalogEntries({
providerType: 'custom',
diff --git a/packages/core/src/__tests__/models-dev-refresh.test.ts b/packages/core/src/__tests__/models-dev-refresh.test.ts
index 5fa08a75c4..237985a396 100644
--- a/packages/core/src/__tests__/models-dev-refresh.test.ts
+++ b/packages/core/src/__tests__/models-dev-refresh.test.ts
@@ -22,6 +22,24 @@ import { test } from 'node:test';
import { MODELS_DEV_PROVIDERS } from '../models-dev-projection.js';
import { MODELS_DEV_RESPONSE_MAX_BYTES, fetchModelsDevProjection } from '../models-dev-refresh.js';
+test('a stale MiniMax refresh keeps the current direct text catalog and unrelated providers', async () => {
+ const upstream = catalog();
+ const metadata = await fetchModelsDevProjection({
+ fetch: respondWith(JSON.stringify(upstream)),
+ previous: {},
+ onRemovals: () => {},
+ });
+ for (const providerType of ['MiniMax', 'MiniMax-cn'] as const) {
+ assert.deepEqual(Object.keys(metadata[providerType] ?? {}), [
+ 'MiniMax-M3.1-Flash',
+ 'MiniMax-M3',
+ ]);
+ assert.equal(metadata[providerType]?.['MiniMax-M3.1-Flash']?.maxOutputTokens, 524_288);
+ }
+ assert.equal(metadata['minimax-coding-plan']?.['MiniMax-M3.1-Flash'], undefined);
+ assert.ok(metadata.anthropic?.['claude-kept']);
+});
+
test('a refresh reports every committed path upstream stopped carrying', async () => {
const removals: string[][] = [];
const metadata = await fetchModelsDevProjection({
diff --git a/packages/core/src/model-catalog.ts b/packages/core/src/model-catalog.ts
index 77b0257a0c..907ec854a5 100644
--- a/packages/core/src/model-catalog.ts
+++ b/packages/core/src/model-catalog.ts
@@ -37,6 +37,7 @@ import {
providerSupportsModelDiscovery,
} from './llm-connections.js';
import { isRetiredProvider } from './provider-retirement.js';
+import { MINIMAX_TEXT_MODEL_IDS } from './models-dev-projection.js';
import { lookupModelMetadata, resolveModelVisionSupport } from './model-metadata.js';
import {
modelOverride,
@@ -132,7 +133,7 @@ export function buildModelCatalogEntries(input: BuildModelCatalogInput): ModelCa
// shape of a failed or not-yet-run discovery. It must not hide the static
// fallback catalog from the picker. An empty fetched array is different: it
// is an authoritative provider response and should remain empty.
- const rawModels =
+ let rawModels: ModelInfo[] =
liveModels !== undefined && (liveModels.length > 0 || modelSource === 'fetched')
? liveModels
: (input.fallbackModels ?? []).map((id) => ({
@@ -140,6 +141,26 @@ export function buildModelCatalogEntries(input: BuildModelCatalogInput): ModelCa
...displayNameForKnownModel(input.providerType, id),
}));
const savedModelIds = normalizedIdSet(input.savedModelIds);
+ if (input.providerType === 'MiniMax' || input.providerType === 'MiniMax-cn') {
+ // Discovery can lag a release. Keep the current direct text pair first,
+ // preserving custom/non-text entries and restoring saved legacy IDs below.
+ const discovered = new Map(rawModels.map((model) => [model.id, model]));
+ rawModels = [
+ ...MINIMAX_TEXT_MODEL_IDS.map((id) => ({
+ ...discovered.get(id),
+ id,
+ ...lookupModelMetadata(input.providerType, id),
+ })),
+ ...rawModels.filter(
+ (model) =>
+ !MINIMAX_TEXT_MODEL_IDS.some((id) => id === model.id) &&
+ (!/^MiniMax-(?:M1|M2|Text)(?:[.-]|$)/i.test(model.id) ||
+ model.id === normalizedDefaultModel ||
+ savedModelIds.has(model.id) ||
+ (model.modalities?.output && !model.modalities.output.includes('text'))),
+ ),
+ ];
+ }
const ctx: EntryContext = { input, normalizedDefaultModel };
const seen = new Set<string>();
const entries = rawModels
diff --git a/packages/core/src/model-metadata.ts b/packages/core/src/model-metadata.ts
index 37c0feaecb..24142a8177 100644
--- a/packages/core/src/model-metadata.ts
+++ b/packages/core/src/model-metadata.ts
@@ -19,6 +19,7 @@
import type { ModelInfo, ProviderType, ProviderRuntimeAdapter } from './llm-connections.js';
import type { ThinkingOptions } from './model-thinking.js';
+import { withMiniMaxTextCatalog } from './models-dev-projection.js';
import {
GENERATED_MODELS_DEV_METADATA,
GENERATED_MODELS_DEV_MODEL_PROVIDER_OVERRIDES,
@@ -64,7 +65,7 @@ let refreshedMetadata: ModelsDevMetadata | undefined;
*/
export function installRefreshedModelMetadata(metadata: ModelsDevMetadata | undefined): void {
if (metadata !== undefined) assertWireTokenLimits(metadata);
- refreshedMetadata = metadata;
+ refreshedMetadata = metadata === undefined ? undefined : withMiniMaxTextCatalog(metadata);
}
/**
@@ -509,6 +510,12 @@ const COMMAND_CODE_MODEL_METADATA: Record<string, ModelMetadata> = {
'MiniMaxAI/MiniMax-M3': { thinkingOptions: { efforts: ['low', 'medium', 'high'] } },
};
+const MINIMAX_MODEL_OVERRIDES: Record<string, ModelMetadata> = {
+ 'MiniMax-M3': {
+ thinkingOptions: { toggle: true, offBehavior: 'anthropic-thinking-disabled' },
+ },
+};
+
// Facts that models.dev cannot express: provider wire controls and
// access-path-specific aliases/limits. Standard model facts stay generated.
//
@@ -516,6 +523,8 @@ const COMMAND_CODE_MODEL_METADATA: Record<string, ModelMetadata> = {
// derived from a provider's catalog cover models a refresh introduced.
function buildStaticModelMetadata(active: ModelsDevMetadata): ModelsDevMetadata {
return {
+ MiniMax: MINIMAX_MODEL_OVERRIDES,
+ 'MiniMax-cn': MINIMAX_MODEL_OVERRIDES,
anthropic: ANTHROPIC_MODEL_OVERRIDES,
opencode: {
'claude-sonnet-4-5': {
diff --git a/packages/core/src/models-dev-projection.ts b/packages/core/src/models-dev-projection.ts
index 1d14405448..627f3b43ca 100644
--- a/packages/core/src/models-dev-projection.ts
+++ b/packages/core/src/models-dev-projection.ts
@@ -36,6 +36,47 @@ import type { ModelMetadata } from './model-metadata.js';
export const MODELS_DEV_SOURCE_URL = 'https://models.dev/api.json';
+// Direct API release facts take precedence over the lagging models.dev catalog.
+// https://platform.minimax.io/docs/guides/models-intro.md
+// https://platform.minimax.io/docs/api-reference/text-chat-anthropic.md
+export const MINIMAX_TEXT_MODEL_IDS = ['MiniMax-M3.1-Flash', 'MiniMax-M3'] as const;
+const MINIMAX_TEXT_METADATA: Record<string, ModelMetadata> = Object.fromEntries(
+ MINIMAX_TEXT_MODEL_IDS.map((id) => [
+ id,
+ {
+ displayName: id,
+ lifecycle: 'active',
+ contextWindow: 1_000_000,
+ maxOutputTokens: 524_288,
+ capabilities: { vision: true, reasoning: true, functionCalling: true },
+ modalities: { input: ['text', 'image', 'video'], output: ['text'] },
+ thinkingOptions:
+ id === 'MiniMax-M3.1-Flash'
+ ? { efforts: ['low', 'medium', 'high', 'xhigh', 'max'] }
+ : { toggle: true },
+ },
+ ]),
+);
+
+/** Preserve non-text catalogs; this policy never touches saved connection models. */
+export function withMiniMaxTextCatalog<
+ T extends Partial<Record<ProviderType, Record<string, ModelMetadata>>>,
+>(metadata: T): T {
+ const result = { ...metadata };
+ for (const providerType of ['MiniMax', 'MiniMax-cn'] as const) {
+ if (!metadata[providerType]) continue;
+ result[providerType] = {
+ ...MINIMAX_TEXT_METADATA,
+ ...Object.fromEntries(
+ Object.entries(metadata[providerType]).filter(
+ ([, model]) => model.modalities?.output && !model.modalities.output.includes('text'),
+ ),
+ ),
+ };
+ }
+ return result;
+}
+
/** Every provider access path Maka serves, and the models.dev provider it reads. */
export const MODELS_DEV_PROVIDERS = {
anthropic: 'anthropic',
@@ -212,7 +253,7 @@ export function projectModelsDevMetadata(
.map(([id, model]) => [id, projectModelsDevModel(sourceId, id, provider, model)]),
);
}
- return metadata;
+ return withMiniMaxTextCatalog(metadata);
}
export function projectModelsDevModel(
diff --git a/packages/core/src/provider-registry.ts b/packages/core/src/provider-registry.ts
index 878e3df806..22baede400 100644
--- a/packages/core/src/provider-registry.ts
+++ b/packages/core/src/provider-registry.ts
@@ -953,7 +953,7 @@ const providerRegistry = {
label: 'MiniMax',
baseUrl: 'https://api.minimax.io/anthropic/v1',
authKind: 'api_key',
- fallbackModels: ['MiniMax-M3', 'MiniMax-M2.7'],
+ fallbackModels: ['MiniMax-M3.1-Flash', 'MiniMax-M3'],
status: 'ready',
runtimeAdapter: { kind: 'anthropic', auth: 'bearer', normalizeBaseUrl: false },
modelDiscovery: { kind: 'protocol' },
@@ -966,7 +966,7 @@ const providerRegistry = {
label: 'MiniMax 中国站',
baseUrl: 'https://api.minimaxi.com/anthropic/v1',
authKind: 'api_key',
- fallbackModels: ['MiniMax-M3', 'MiniMax-M2.7'],
+ fallbackModels: ['MiniMax-M3.1-Flash', 'MiniMax-M3'],
status: 'ready',
runtimeAdapter: { kind: 'anthropic', auth: 'bearer', normalizeBaseUrl: false },
modelDiscovery: { kind: 'protocol' },
diff --git a/packages/runtime/src/__tests__/model-factory-thinking.test.ts b/packages/runtime/src/__tests__/model-factory-thinking.test.ts
index 0bfc3f0c24..d918691a15 100644
--- a/packages/runtime/src/__tests__/model-factory-thinking.test.ts
+++ b/packages/runtime/src/__tests__/model-factory-thinking.test.ts
@@ -51,6 +51,91 @@ function custom(
}
describe('buildProviderOptions: thinking level', () => {
+ test('MiniMax direct release pricing has unique rows and no coding-plan Flash price', async () => {
+ const { BUILTIN_PRICING, getBuiltinPricing } = await import('../telemetry/builtin-pricing.js');
+ for (const providerType of ['MiniMax', 'MiniMax-cn']) {
+ const modelKey = `${providerType}:MiniMax-M3.1-Flash`;
+ assert.deepEqual(getBuiltinPricing(modelKey), {
+ modelKey,
+ inputUsdPer1M: 0.15,
+ outputUsdPer1M: 0.6,
+ cacheReadUsdPer1M: 0.015,
+ });
+ assert.equal(BUILTIN_PRICING.filter((row) => row.modelKey === modelKey).length, 1);
+ assert.equal(getBuiltinPricing(`${providerType}:MiniMax-M3`)?.cacheReadUsdPer1M, 0.06);
+ }
+ assert.equal(getBuiltinPricing('minimax-coding-plan:MiniMax-M3.1-Flash'), null);
+ });
+ test('MiniMax-M3 exposes off and sends disabled thinking on both regional providers', () => {
+ for (const providerType of ['MiniMax', 'MiniMax-cn'] as const) {
+ assert.deepEqual([...thinkingVariantsForModel(providerType, 'MiniMax-M3')], ['off', 'on']);
+ assert.deepEqual(buildProviderOptions(conn(providerType), 'MiniMax-M3', 'on'), {
+ anthropic: { thinking: { type: 'adaptive' } },
+ });
+ assert.deepEqual(buildProviderOptions(conn(providerType), 'MiniMax-M3', 'off'), {
+ anthropic: { thinking: { type: 'disabled' } },
+ });
+ assert.deepEqual(buildProviderOptions(conn(providerType), 'MiniMax-M3'), { anthropic: {} });
+ assert.deepEqual(buildProviderOptions(conn(providerType), 'MiniMax-M3', 'high'), {
+ anthropic: {},
+ });
+ }
+ });
+
+ test('MiniMax Flash efforts survive SDK serialization without disabled thinking or service tier', async () => {
+ for (const providerType of ['MiniMax', 'MiniMax-cn'] as const) {
+ const connection = conn(providerType);
+ const modelId = 'MiniMax-M3.1-Flash';
+ const levels = ['low', 'medium', 'high', 'xhigh', 'max'] as const;
+ assert.deepEqual(thinkingVariantsForModel(providerType, modelId), levels);
+ for (const level of [undefined, ...levels, 'off', 'on'] as const) {
+ let body: Record<string, unknown> = {};
+ await getAIModel({
+ connection,
+ modelId,
+ apiKey: 'test-key',
+ fetch: async (_input, init) => {
+ body = JSON.parse(String(init?.body));
+ return Response.json({
+ id: 'msg-1',
+ type: 'message',
+ role: 'assistant',
+ model: modelId,
+ content: [{ type: 'text', text: 'ok' }],
+ stop_reason: 'end_turn',
+ usage: { input_tokens: 1, output_tokens: 1 },
+ });
+ },
+ }).doGenerate({
+ prompt: [{ role: 'user', content: [{ type: 'text', text: 'hi' }] }],
+ providerOptions: buildProviderOptions(
+ {
+ ...connection,
+ modelOverrides: { [modelId]: { thinkingLevels: [...levels, 'off', 'on'] } },
+ },
+ modelId,
+ level,
+ ),
+ });
+ assert.deepEqual(body.thinking, { type: 'adaptive' });
+ assert.deepEqual(body.output_config, {
+ effort: level && level !== 'off' && level !== 'on' ? level : 'max',
+ });
+ assert.equal(body.service_tier, undefined);
+ assert.equal(body.reasoning_effort, undefined);
+ }
+ }
+ });
+
+ test('MiniMax-M2.7 remains always on for both regional providers', () => {
+ for (const providerType of ['MiniMax', 'MiniMax-cn'] as const) {
+ assert.deepEqual([...thinkingVariantsForModel(providerType, 'MiniMax-M2.7')], []);
+ assert.deepEqual(buildProviderOptions(conn(providerType), 'MiniMax-M2.7', 'off'), {
+ anthropic: {},
+ });
+ }
+ });
+
test('provider defaults reach the SDK request body without thinking overrides', async () => {
for (const [connection, modelId] of [
[conn('openai'), 'gpt-5.5'],
diff --git a/packages/runtime/src/model-factory.ts b/packages/runtime/src/model-factory.ts
index 281b207d8c..6853b79dd3 100644
--- a/packages/runtime/src/model-factory.ts
+++ b/packages/runtime/src/model-factory.ts
@@ -539,6 +539,16 @@ function buildThinkingProviderOptions(
connection.providerType === 'anthropic' ? claudeThinkingOptions(modelId, level) : undefined;
if (level === 'off' && thinkingOptions?.offBehavior === 'anthropic-thinking-disabled') {
reasoning = { thinking: { type: 'disabled' as const } };
+ } else if (
+ (connection.providerType === 'MiniMax' || connection.providerType === 'MiniMax-cn') &&
+ (modelId === 'MiniMax-M3.1-Flash' || (modelId === 'MiniMax-M3' && level === 'on'))
+ ) {
+ reasoning = {
+ thinking: { type: 'adaptive' as const },
+ ...(modelId === 'MiniMax-M3.1-Flash'
+ ? { effort: level && level !== 'off' && level !== 'on' ? level : 'max' }
+ : {}),
+ };
} else if (summarizedThinking) {
reasoning = summarizedThinking;
} else if (level && level !== 'off' && level !== 'on') {
diff --git a/packages/runtime/src/telemetry/builtin-pricing.ts b/packages/runtime/src/telemetry/builtin-pricing.ts
index 059ed31271..4889c61a7e 100644
--- a/packages/runtime/src/telemetry/builtin-pricing.ts
+++ b/packages/runtime/src/telemetry/builtin-pricing.ts
@@ -79,11 +79,34 @@ const LOCAL_PRICING_SUPPLEMENT: readonly PricingConfig[] = [
},
];
+// https://platform.minimax.io/docs/pricing/overview.md (USD per million tokens).
+// M3 uses Standard <=512k estimates. This flat schema cannot represent its
+// >512k rates (0.60/2.40/0.12) or Priority's 1.5x multiplier.
+const MINIMAX_RELEASE_PRICING: readonly PricingConfig[] = ['MiniMax', 'MiniMax-cn'].flatMap(
+ (provider) => [
+ {
+ modelKey: `${provider}:MiniMax-M3.1-Flash`,
+ inputUsdPer1M: 0.15,
+ outputUsdPer1M: 0.6,
+ cacheReadUsdPer1M: 0.015,
+ },
+ {
+ modelKey: `${provider}:MiniMax-M3`,
+ inputUsdPer1M: 0.3,
+ outputUsdPer1M: 1.2,
+ cacheReadUsdPer1M: 0.06,
+ },
+ ],
+);
+const releasePricingKeys = new Set(MINIMAX_RELEASE_PRICING.map(({ modelKey }) => modelKey));
const generatedPricingKeys = new Set(GENERATED_MODEL_PRICING.map(({ modelKey }) => modelKey));
export const BUILTIN_PRICING: readonly PricingConfig[] = [
- ...GENERATED_MODEL_PRICING,
- ...LOCAL_PRICING_SUPPLEMENT.filter(({ modelKey }) => !generatedPricingKeys.has(modelKey)),
+ ...MINIMAX_RELEASE_PRICING,
+ ...GENERATED_MODEL_PRICING.filter(({ modelKey }) => !releasePricingKeys.has(modelKey)),
+ ...LOCAL_PRICING_SUPPLEMENT.filter(
+ ({ modelKey }) => !generatedPricingKeys.has(modelKey) && !releasePricingKeys.has(modelKey),
+ ),
];
const byKey = new Map(BUILTIN_PRICING.map((pricing) => [pricing.modelKey, pricing]));
diff --git a/scripts/sync-model-metadata.mjs b/scripts/sync-model-metadata.mjs
index 4362da220d..c3a7e7af25 100644
--- a/scripts/sync-model-metadata.mjs
+++ b/scripts/sync-model-metadata.mjs
@@ -100,6 +100,12 @@ export async function main(argv = process.argv) {
const source = refresh
? await refreshSnapshot(snapshotPath, refreshInputPath, { acceptUpstreamRemovals })
: await loadSnapshot(snapshotPath);
+ // Keep the source snapshot intact; official direct-API facts override its
+ // lagging text catalog in both offline generation and refresh/check output.
+ source.projection = {
+ ...source.projection,
+ metadata: projection.withMiniMaxTextCatalog(source.projection.metadata),
+ };
const {
metadata: generated,
pricing: generatedPricing,
diff --git a/scripts/sync-model-metadata.test.mjs b/scripts/sync-model-metadata.test.mjs
index 35ddb0a5f4..c274b59f80 100644
--- a/scripts/sync-model-metadata.test.mjs
+++ b/scripts/sync-model-metadata.test.mjs
@@ -75,6 +75,16 @@ test('the committed snapshot generates both TypeScript modules offline', async (
]);
assert.ok(Object.keys(metadataModule.GENERATED_MODELS_DEV_METADATA).length > 0);
+ for (const provider of ['MiniMax', 'MiniMax-cn']) {
+ const models = metadataModule.GENERATED_MODELS_DEV_METADATA[provider];
+ assert.deepEqual(Object.keys(models), ['MiniMax-M3.1-Flash', 'MiniMax-M3']);
+ assert.equal(models['MiniMax-M3.1-Flash'].contextWindow, 1_000_000);
+ assert.equal(models['MiniMax-M3.1-Flash'].maxOutputTokens, 524_288);
+ }
+ assert.equal(
+ metadataModule.GENERATED_MODELS_DEV_METADATA['minimax-coding-plan']['MiniMax-M3.1-Flash'],
+ undefined,
+ );
assert.ok(Array.isArray(pricingModule.GENERATED_MODEL_PRICING));
assert.ok(pricingModule.GENERATED_MODEL_PRICING.length > 0);
} finally {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org