@telora/mcp-products 0.22.145 → 0.22.147
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.
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { type GetCreds, type ToolProfile } from "../shared.js";
|
|
3
|
-
export declare const
|
|
4
|
-
export declare function
|
|
3
|
+
export declare const SELECTABLE_PASS_MODEL_IDS: ReadonlySet<string>;
|
|
4
|
+
export declare function isSelectablePassModelId(id: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* The telora_organization tool description. The accepted ids are rendered from
|
|
7
|
+
* SELECTABLE_PASS_MODEL_IDS, so the description cannot drift from what the
|
|
8
|
+
* handler (and the settings page, via the registry drift test) accepts.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ORGANIZATION_TOOL_DESCRIPTION: string;
|
|
5
11
|
type CallApi = (body: Record<string, unknown>) => Promise<unknown>;
|
|
6
12
|
export interface OrgPassModelsParams {
|
|
7
13
|
action: "get_pass_models" | "set_pass_models";
|
|
@@ -3,26 +3,51 @@
|
|
|
3
3
|
// telora_organization (get_pass_models | set_pass_models)
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
5
|
//
|
|
6
|
-
// The org's per-pass DEFAULT models (coding, review) -- the model
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// so no org id rides the request.
|
|
6
|
+
// The org's per-pass DEFAULT models (coding, review) -- the model a focus pass
|
|
7
|
+
// runs when nothing more specific picks one. This is the harness-facing
|
|
8
|
+
// equivalent of the dashboard's Settings > Default Pass Models pickers, and it
|
|
9
|
+
// accepts exactly what they save: a selectable hosted model id, or a clear.
|
|
10
|
+
// Model ids are validated against the registry here AND in product-api; ids are
|
|
11
|
+
// forwarded trimmed, as the settings RPC stores them. The org is resolved from
|
|
12
|
+
// the tracker, so no org id rides the request.
|
|
13
|
+
//
|
|
14
|
+
// Which ENGINE runs the model is the @telora/daemon-core resolvePassEngine rule
|
|
15
|
+
// (one ladder across models and engines, most-specific first): focus pin >
|
|
16
|
+
// org-authored workflow stage > org default > product default engine
|
|
17
|
+
// (daemon.json) > builtin workflow stage > global default. A model runs on the
|
|
18
|
+
// engine it implies when its layer is at least as specific as the engine's.
|
|
13
19
|
import { z } from "zod";
|
|
14
20
|
import { callProductApi, successResult, validationError, wrapHandler, } from "../shared.js";
|
|
15
|
-
// Hosted model registry ids an org default may be set to
|
|
16
|
-
// src/lib/agents/models.ts MODEL_REGISTRY (the MCP does
|
|
17
|
-
// registry); drift is pinned by
|
|
21
|
+
// Hosted model registry ids an org default may be NEWLY set to: the selectable
|
|
22
|
+
// (status 'current') ids of src/lib/agents/models.ts MODEL_REGISTRY (the MCP does
|
|
23
|
+
// not import the frontend registry); drift is pinned by
|
|
24
|
+
// src/lib/agents/__tests__/passModelRegistryDrift.test.ts. A legacy id is refused
|
|
25
|
+
// for a new selection; an org already pinned to one still reads it back, and a
|
|
26
|
+
// write that omits that pass leaves it untouched.
|
|
18
27
|
// '' clears (inherit the builtin stage / backend default).
|
|
19
|
-
export const
|
|
20
|
-
"claude-fable-5-1", "claude-
|
|
21
|
-
"claude-haiku-4-5-20251001", "gpt-
|
|
28
|
+
export const SELECTABLE_PASS_MODEL_IDS = new Set([
|
|
29
|
+
"claude-fable-5-1", "claude-opus-5", "claude-opus-4-8", "claude-sonnet-5",
|
|
30
|
+
"claude-haiku-4-5-20251001", "gpt-6-astra", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna",
|
|
22
31
|
]);
|
|
23
|
-
export function
|
|
24
|
-
return
|
|
32
|
+
export function isSelectablePassModelId(id) {
|
|
33
|
+
return SELECTABLE_PASS_MODEL_IDS.has(id.trim());
|
|
25
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* The telora_organization tool description. The accepted ids are rendered from
|
|
37
|
+
* SELECTABLE_PASS_MODEL_IDS, so the description cannot drift from what the
|
|
38
|
+
* handler (and the settings page, via the registry drift test) accepts.
|
|
39
|
+
*/
|
|
40
|
+
export const ORGANIZATION_TOOL_DESCRIPTION = "Organization settings: the org's per-pass DEFAULT models (coding, review) -- the model a focus pass runs when the focus pins none. " +
|
|
41
|
+
"The harness equivalent of the dashboard's Settings > Default Pass Models pickers, and it accepts exactly what they save: " +
|
|
42
|
+
`a selectable hosted model id (${[...SELECTABLE_PASS_MODEL_IDS].join(", ")}), or an empty string to clear (inherit). ` +
|
|
43
|
+
"Legacy ids that are no longer selectable (e.g. gpt-5-codex, gpt-5, o3-mini, claude-fable-5) are refused; an org already pinned to one still reads it back. " +
|
|
44
|
+
"Model precedence: a focus pin > an org-authored workflow stage model > this org default > the builtin workflow stage model. " +
|
|
45
|
+
"Engine: the daemon runs a model on the engine it implies (claude-* on Claude Code, gpt-* on Codex) when the model's layer outranks the pass's engine choice, on one ladder: " +
|
|
46
|
+
"focus > org-authored workflow stage > org default > product default engine (daemon.json on the daemon host) > builtin workflow stage > global default. " +
|
|
47
|
+
"So an org default gpt-* model runs on Codex even when the org or product default engine is Claude Code (and an org default claude-* model runs on Claude Code on a Codex-harness product), " +
|
|
48
|
+
"but a focus engine override or an org-authored stage engine outranks it; " +
|
|
49
|
+
"a model the chosen engine cannot run is dropped and that engine runs its own default. " +
|
|
50
|
+
"Actions: get_pass_models (read the current defaults), set_pass_models (write; only the passes you provide change; an empty string clears -> inherit).";
|
|
26
51
|
/**
|
|
27
52
|
* Pure handler -- exported for testing with a mock callApi (the MCP test
|
|
28
53
|
* convention). Reads or writes the org per-pass default models. A model id is
|
|
@@ -42,15 +67,17 @@ export async function handleOrganizationPassModels(params, callApi) {
|
|
|
42
67
|
if (!params.canWrite)
|
|
43
68
|
return validationError("set_pass_models is not available in this profile");
|
|
44
69
|
for (const [key, value] of [["codingModel", params.codingModel], ["reviewModel", params.reviewModel]]) {
|
|
45
|
-
if (value !== undefined && value.trim() !== "" && !
|
|
70
|
+
if (value !== undefined && value.trim() !== "" && !isSelectablePassModelId(value)) {
|
|
46
71
|
return validationError(`Invalid ${key} id: ${value}`);
|
|
47
72
|
}
|
|
48
73
|
}
|
|
74
|
+
// Forward trimmed: the stored value is exactly what the settings page saves
|
|
75
|
+
// (its RPC stores NULLIF(TRIM(id), '')), and a blank string is a clear.
|
|
49
76
|
const body = { action: "set_org_pass_models" };
|
|
50
77
|
if (params.codingModel !== undefined)
|
|
51
|
-
body.codingModel = params.codingModel;
|
|
78
|
+
body.codingModel = params.codingModel.trim();
|
|
52
79
|
if (params.reviewModel !== undefined)
|
|
53
|
-
body.reviewModel = params.reviewModel;
|
|
80
|
+
body.reviewModel = params.reviewModel.trim();
|
|
54
81
|
const r = (await callApi(body));
|
|
55
82
|
return successResult({ codingModel: r.codingModel ?? null, reviewModel: r.reviewModel ?? null });
|
|
56
83
|
}
|
|
@@ -60,11 +87,10 @@ export async function handleOrganizationPassModels(params, callApi) {
|
|
|
60
87
|
}
|
|
61
88
|
export function registerOrganizationTools(server, getCreds, profile = "full") {
|
|
62
89
|
const canWrite = profile === "full" || profile === "human";
|
|
63
|
-
server.tool("telora_organization",
|
|
64
|
-
"Actions: get_pass_models (read the current defaults), set_pass_models (write; only the passes you provide change; an empty string clears -> inherit). Model ids are validated against the registry server-side.", {
|
|
90
|
+
server.tool("telora_organization", ORGANIZATION_TOOL_DESCRIPTION, {
|
|
65
91
|
action: z.enum(["get_pass_models", "set_pass_models"]).describe("Action to perform"),
|
|
66
|
-
codingModel: z.string().optional().describe("Coding-pass default model id (set_pass_models). Empty string clears (inherit); omit to leave unchanged."),
|
|
67
|
-
reviewModel: z.string().optional().describe("Review-pass default model id (set_pass_models). Empty string clears (inherit); omit to leave unchanged."),
|
|
92
|
+
codingModel: z.string().optional().describe("Coding-pass default model id (set_pass_models): a selectable Claude or OpenAI hosted id. Empty string clears (inherit); omit to leave unchanged."),
|
|
93
|
+
reviewModel: z.string().optional().describe("Review-pass default model id (set_pass_models): a selectable Claude or OpenAI hosted id. Empty string clears (inherit); omit to leave unchanged."),
|
|
68
94
|
}, wrapHandler(async (params) => handleOrganizationPassModels({ action: params.action, codingModel: params.codingModel, reviewModel: params.reviewModel, canWrite }, (body) => callProductApi(getCreds(), body))));
|
|
69
95
|
}
|
|
70
96
|
//# sourceMappingURL=organizationHandlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationHandlers.js","sourceRoot":"","sources":["../../src/handlers/organizationHandlers.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6CAA6C;AAC7C,4DAA4D;AAC5D,8EAA8E;AAC9E,EAAE;AACF
|
|
1
|
+
{"version":3,"file":"organizationHandlers.js","sourceRoot":"","sources":["../../src/handlers/organizationHandlers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telora/mcp-products",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.147",
|
|
4
4
|
"description": "MCP server exposing Telora product operations to Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
41
|
-
"@telora/daemon-core": "^0.2.
|
|
41
|
+
"@telora/daemon-core": "^0.2.97",
|
|
42
42
|
"ts-morph": "^28.0.0",
|
|
43
43
|
"zod": "^4.3.6"
|
|
44
44
|
},
|