@orthacms/copilot-server 0.4.2 → 0.4.3
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/dist/lib/chat/application/run-engine.service.d.ts +10 -1
- package/dist/lib/chat/application/run-engine.service.d.ts.map +1 -1
- package/dist/lib/chat/application/run-engine.service.js +16 -4
- package/dist/lib/copilot.module.d.ts.map +1 -1
- package/dist/lib/copilot.module.js +55 -31
- package/dist/lib/infrastructure/model-registry.d.ts +1 -1
- package/dist/lib/infrastructure/model-registry.d.ts.map +1 -1
- package/dist/lib/utils/copilot-plugin.d.ts +9 -2
- package/dist/lib/utils/copilot-plugin.d.ts.map +1 -1
- package/dist/lib/utils/copilot-plugin.js +21 -9
- package/package.json +7 -7
|
@@ -69,7 +69,16 @@ export interface StartRunInput {
|
|
|
69
69
|
export declare class UnknownModelChoiceError extends Error {
|
|
70
70
|
constructor(message: string);
|
|
71
71
|
}
|
|
72
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* Thrown when a run cannot start at all — the controller turns it into an
|
|
74
|
+
* error frame.
|
|
75
|
+
*
|
|
76
|
+
* **Rarely reachable over HTTP**: the copilot's kill switch now unregisters
|
|
77
|
+
* every controller (`copilot.module.ts`), so a disabled deployment 404s the run
|
|
78
|
+
* route rather than opening a stream to say no. Kept because the engine is
|
|
79
|
+
* drainable without a socket, and a caller that gets one anyway deserves a
|
|
80
|
+
* named reason rather than a 500.
|
|
81
|
+
*/
|
|
73
82
|
export declare class CopilotDisabledError extends Error {
|
|
74
83
|
constructor();
|
|
75
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-engine.service.d.ts","sourceRoot":"","sources":["../../../../src/lib/chat/application/run-engine.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAcH,KAAK,kBAAkB,EACvB,KAAK,eAAe,EAGpB,KAAK,aAAa,EAClB,KAAK,aAAa,EAKlB,KAAK,SAAS,EAKjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACH,YAAY,EAGf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AACvF,OAAO,EACH,wBAAwB,EAE3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAC;AAErF,OAAO,EAGH,KAAK,cAAc,EACtB,MAAM,iBAAiB,CAAC;AAEzB,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC1B,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,yBAAyB;IACzB,OAAO,EAAE,cAAc,CAAC;IACxB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;;OAKG;IACH,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,2CAA2C;IAC3C,MAAM,EAAE,WAAW,CAAC;CACvB;AAED;;;;GAIG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI9B;AAED
|
|
1
|
+
{"version":3,"file":"run-engine.service.d.ts","sourceRoot":"","sources":["../../../../src/lib/chat/application/run-engine.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,7 +28,16 @@ class UnknownModelChoiceError extends Error {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
exports.UnknownModelChoiceError = UnknownModelChoiceError;
|
|
31
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Thrown when a run cannot start at all — the controller turns it into an
|
|
33
|
+
* error frame.
|
|
34
|
+
*
|
|
35
|
+
* **Rarely reachable over HTTP**: the copilot's kill switch now unregisters
|
|
36
|
+
* every controller (`copilot.module.ts`), so a disabled deployment 404s the run
|
|
37
|
+
* route rather than opening a stream to say no. Kept because the engine is
|
|
38
|
+
* drainable without a socket, and a caller that gets one anyway deserves a
|
|
39
|
+
* named reason rather than a 500.
|
|
40
|
+
*/
|
|
32
41
|
class CopilotDisabledError extends Error {
|
|
33
42
|
constructor() {
|
|
34
43
|
super('The copilot is disabled.');
|
|
@@ -81,9 +90,12 @@ let RunEngine = RunEngine_1 = class RunEngine {
|
|
|
81
90
|
/** Runs one turn, yielding events as they happen. */
|
|
82
91
|
async *run(input) {
|
|
83
92
|
if (!this.config.enabled) {
|
|
84
|
-
// The operator's kill switch (ADR-0005 §10)
|
|
85
|
-
//
|
|
86
|
-
//
|
|
93
|
+
// The operator's kill switch (ADR-0005 §10), belt-and-braces —
|
|
94
|
+
// `CopilotModule.forRoot` registers no controller when it is off,
|
|
95
|
+
// so a disabled deployment 404s before it reaches this line. This
|
|
96
|
+
// is the guard against a future wiring change, and against a
|
|
97
|
+
// caller that drains the generator without going through HTTP
|
|
98
|
+
// (a tool, a job, a test).
|
|
87
99
|
throw new CopilotDisabledError();
|
|
88
100
|
}
|
|
89
101
|
const runId = (0, node_crypto_1.randomUUID)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot.module.d.ts","sourceRoot":"","sources":["../../src/lib/copilot.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAIH,KAAK,aAAa,EAClB,KAAK,eAAe,EACvB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAEH,KAAK,oBAAoB,EAC5B,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAqBlE,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACjC,sEAAsE;IACtE,SAAS,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC3C,0DAA0D;IAC1D,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,+DAA+D;IAC/D,MAAM,EAAE,mBAAmB,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,qBACa,aAAa;IACtB,mEAAmE;IACnE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa;
|
|
1
|
+
{"version":3,"file":"copilot.module.d.ts","sourceRoot":"","sources":["../../src/lib/copilot.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAIH,KAAK,aAAa,EAClB,KAAK,eAAe,EACvB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAEH,KAAK,oBAAoB,EAC5B,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAqBlE,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACjC,sEAAsE;IACtE,SAAS,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC3C,0DAA0D;IAC1D,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,+DAA+D;IAC/D,MAAM,EAAE,mBAAmB,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,qBACa,aAAa;IACtB,mEAAmE;IACnE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa;CAiI/D"}
|
|
@@ -47,11 +47,17 @@ let CopilotModule = CopilotModule_1 = class CopilotModule {
|
|
|
47
47
|
// and its order is the preference order (`catalogue()` renders in it,
|
|
48
48
|
// and the admin's picker opens on its first entry).
|
|
49
49
|
const [first] = options.providers;
|
|
50
|
-
if (!first) {
|
|
51
|
-
throw new Error('CopilotModule
|
|
50
|
+
if (!first && options.config.enabled) {
|
|
51
|
+
throw new Error('CopilotModule is enabled but has no model provider — the first one registered ' +
|
|
52
52
|
'is what serves a run that names none.');
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
// A disabled copilot registers no controller, so nothing can reach the
|
|
55
|
+
// resolver and there is no default to name. It still has to resolve to
|
|
56
|
+
// *something*: the module binds `MODEL_RESOLVER` either way, because the
|
|
57
|
+
// switch must not change the shape of the DI graph. Asking for a
|
|
58
|
+
// provider through it fails in `ModelRegistry.get`, naming the empty
|
|
59
|
+
// catalogue, which is the same error an unknown name gets.
|
|
60
|
+
const resolver = options.resolve ?? (() => first?.name ?? '');
|
|
55
61
|
return {
|
|
56
62
|
module: CopilotModule_1,
|
|
57
63
|
global: true,
|
|
@@ -62,34 +68,52 @@ let CopilotModule = CopilotModule_1 = class CopilotModule {
|
|
|
62
68
|
// so a deployment running the copilot *without* MCP still has one,
|
|
63
69
|
// and one running both has exactly one.
|
|
64
70
|
imports: [database_1.DatabaseModule, tools_server_1.ToolsModule],
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
71
|
+
// **The kill switch, applied where MCP applies its own**
|
|
72
|
+
// (`mcp.module.ts`): a disabled deployment registers no copilot
|
|
73
|
+
// controller at all, so every `/api/copilot/*` route 404s.
|
|
74
|
+
//
|
|
75
|
+
// It used to be read in one place only — `RunEngine.run` — which
|
|
76
|
+
// made "off" mean *the send button returns an error frame*. The
|
|
77
|
+
// panel, the Agents view, the model catalogue, the conversation and
|
|
78
|
+
// skill routes and the tables all stayed live, so a deployment that
|
|
79
|
+
// had opted out still offered the whole feature and refused at the
|
|
80
|
+
// last step. Off is now off.
|
|
81
|
+
//
|
|
82
|
+
// The providers, the registry and the skill catalogue below stay
|
|
83
|
+
// bound either way. They cost nothing unbuilt, and the shared
|
|
84
|
+
// `ToolRegistry` must not change shape with this switch — the MCP
|
|
85
|
+
// endpoint serves the same catalogue, and a tool contributed by
|
|
86
|
+
// `content` is registered against `ToolsModule`, not this one.
|
|
87
|
+
controllers: options.config.enabled
|
|
88
|
+
? [
|
|
89
|
+
create_run_controller_1.CreateRunController,
|
|
90
|
+
// Before `GetConversationController`: `conversations/:id` and
|
|
91
|
+
// `models` can't collide (different first segments), but keep
|
|
92
|
+
// the read routes grouped after the run route.
|
|
93
|
+
list_models_controller_1.ListModelsController,
|
|
94
|
+
list_conversations_controller_1.ListConversationsController,
|
|
95
|
+
// `PATCH conversations/:id`. No ordering hazard with the `GET`
|
|
96
|
+
// wildcard below — Express matches method and path together —
|
|
97
|
+
// but it reads with the other conversation routes.
|
|
98
|
+
update_conversation_controller_1.UpdateConversationController,
|
|
99
|
+
// Before `GetConversationController`, whose `conversations/:id`
|
|
100
|
+
// is the only wildcard here — Express matches in declaration
|
|
101
|
+
// order, so the literal-prefixed routes go first.
|
|
102
|
+
proposals_controller_1.ProposalsController,
|
|
103
|
+
// Before `GetConversationController` for the same reason as
|
|
104
|
+
// the others: its `conversations/:id` is the only wildcard, and
|
|
105
|
+
// Express matches in declaration order.
|
|
106
|
+
tool_permission_controller_1.ToolPermissionController,
|
|
107
|
+
// Both skill controllers before the conversation wildcard, for
|
|
108
|
+
// the same declaration-order reason as the rest. `skills` and
|
|
109
|
+
// `skills/:id` live in different controllers and cannot
|
|
110
|
+
// collide (different segment counts); `skills/manage` is
|
|
111
|
+
// declared above `skills/:id` inside the manage controller.
|
|
112
|
+
list_skills_controller_1.ListSkillsController,
|
|
113
|
+
manage_skills_controller_1.ManageSkillsController,
|
|
114
|
+
get_conversation_controller_1.GetConversationController
|
|
115
|
+
]
|
|
116
|
+
: [],
|
|
93
117
|
providers: [
|
|
94
118
|
{ provide: copilot_tokens_1.COPILOT_CONFIG, useValue: options.config },
|
|
95
119
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ModelProvider, type ModelRegistry } from '@orthacms/copilot-domain';
|
|
2
2
|
/** One provider the host offers, under the name runs refer to it by. */
|
|
3
3
|
export interface ProviderRegistration {
|
|
4
|
-
/** Unique, operator-chosen name — `claude`, `ollama-big`, `
|
|
4
|
+
/** Unique, operator-chosen name — `claude`, `ollama-big`, `local`. */
|
|
5
5
|
name: string;
|
|
6
6
|
/** The adapter instance, already constructed with its own config. */
|
|
7
7
|
provider: ModelProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../../src/lib/infrastructure/model-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,aAAa,EAClB,KAAK,aAAa,EACrB,MAAM,0BAA0B,CAAC;AAElC,wEAAwE;AACxE,MAAM,WAAW,oBAAoB;IACjC,
|
|
1
|
+
{"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../../src/lib/infrastructure/model-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,aAAa,EAClB,KAAK,aAAa,EACrB,MAAM,0BAA0B,CAAC;AAElC,wEAAwE;AACxE,MAAM,WAAW,oBAAoB;IACjC,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,QAAQ,EAAE,aAAa,CAAC;CAC3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAC9B,aAAa,EAAE,SAAS,oBAAoB,EAAE,GAC/C,aAAa,CA+Cf"}
|
|
@@ -20,6 +20,10 @@ export interface CopilotPluginOptions {
|
|
|
20
20
|
* misspelled, could point at a provider nobody registered, and had to be
|
|
21
21
|
* kept in step with this list on every change. A deployment that should
|
|
22
22
|
* not reach a backend does not register it.
|
|
23
|
+
*
|
|
24
|
+
* **May be empty only while `config.enabled` is false.** A copilot that is
|
|
25
|
+
* on and has nothing to call is a misconfiguration, and fails at
|
|
26
|
+
* construction rather than on the first message.
|
|
23
27
|
*/
|
|
24
28
|
providers: readonly ProviderRegistration[];
|
|
25
29
|
/** Optional custom handler picking a provider per run (plain code). */
|
|
@@ -50,13 +54,16 @@ export interface CopilotPluginOptions {
|
|
|
50
54
|
* engine, the capability profile, and the transcript tables this plugin now
|
|
51
55
|
* owns and migrates.
|
|
52
56
|
*
|
|
57
|
+
* Each entry is a backend this deployment actually configured. An enabled
|
|
58
|
+
* copilot needs at least one; a disabled one needs none, and a checkout with no
|
|
59
|
+
* keys registers none.
|
|
60
|
+
*
|
|
53
61
|
* @example
|
|
54
62
|
* ```typescript
|
|
55
63
|
* CopilotPlugin({
|
|
56
64
|
* providers: [
|
|
57
65
|
* { name: 'claude', provider: createAnthropicProvider(providers.claude) },
|
|
58
|
-
* { name: 'ollama', provider: createOpenAiProvider(providers.ollama) }
|
|
59
|
-
* { name: 'fake', provider: createFakeProvider() }
|
|
66
|
+
* { name: 'ollama', provider: createOpenAiProvider(providers.ollama) }
|
|
60
67
|
* ],
|
|
61
68
|
* config: config.plugins.copilot
|
|
62
69
|
* });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/copilot-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAEH,KAAK,aAAa,EAClB,KAAK,eAAe,EACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,0DAA0D;AAC1D,MAAM,MAAM,6BAA6B,GAAG,YAAY,GAAG;IACvD,aAAa,EAAE,mBAAmB,CAAC;CACtC,CAAC;AAEF,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACjC
|
|
1
|
+
{"version":3,"file":"copilot-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/copilot-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAEH,KAAK,aAAa,EAClB,KAAK,eAAe,EACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,0DAA0D;AAC1D,MAAM,MAAM,6BAA6B,GAAG,YAAY,GAAG;IACvD,aAAa,EAAE,mBAAmB,CAAC;CACtC,CAAC;AAEF,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACjC;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC3C,uEAAuE;IACvE,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,+DAA+D;IAC/D,MAAM,EAAE,mBAAmB,CAAC;CAC/B;AA+DD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,aAAa,CACzB,OAAO,EAAE,oBAAoB,GAC9B,6BAA6B,CAa/B"}
|
|
@@ -6,19 +6,28 @@ const copilot_domain_1 = require("@orthacms/copilot-domain");
|
|
|
6
6
|
const copilot_module_1 = require("../copilot.module");
|
|
7
7
|
/**
|
|
8
8
|
* Validate the wiring **eagerly** (like `ContentPlugin`'s registry and
|
|
9
|
-
* `I18nServerPlugin`'s locales):
|
|
10
|
-
*
|
|
11
|
-
* before boot — rather than on the first chat message, where it
|
|
12
|
-
* expensive to diagnose.
|
|
9
|
+
* `I18nServerPlugin`'s locales): a provider declaring no models, or an enabled
|
|
10
|
+
* copilot with no provider at all, is a misconfiguration that should fail at
|
|
11
|
+
* construction — before boot — rather than on the first chat message, where it
|
|
12
|
+
* is most expensive to diagnose.
|
|
13
|
+
*
|
|
14
|
+
* **The empty list is only a misconfiguration when the copilot is on.** A
|
|
15
|
+
* deployment that has not set `enabled` mounts no controllers and can serve no
|
|
16
|
+
* run, so it needs no backend — and that is the ordinary state of a fresh
|
|
17
|
+
* checkout, which configures no keys. There is no scripted offline adapter to
|
|
18
|
+
* fall back on: the fake provider is a private test fixture, so a host with no
|
|
19
|
+
* keys registers nothing rather than registering something that answers every
|
|
20
|
+
* question with a canned sentence.
|
|
13
21
|
*
|
|
14
22
|
* Name uniqueness is enforced by `buildModelRegistry`, which the module builds
|
|
15
23
|
* from the same list.
|
|
16
24
|
*/
|
|
17
25
|
function assertOptions(options) {
|
|
18
26
|
const names = options.providers.map((entry) => entry.name);
|
|
19
|
-
if (names.length === 0) {
|
|
20
|
-
throw new Error('CopilotPlugin
|
|
21
|
-
"e.g. `providers: [{ name: '
|
|
27
|
+
if (names.length === 0 && options.config.enabled) {
|
|
28
|
+
throw new Error('CopilotPlugin is enabled but has no model provider. Configure a backend and register it at ' +
|
|
29
|
+
"the composition root, e.g. `providers: [{ name: 'claude', provider: createAnthropicProvider(…) }]` " +
|
|
30
|
+
'— or leave the copilot off.');
|
|
22
31
|
}
|
|
23
32
|
for (const entry of options.providers) {
|
|
24
33
|
if (entry.provider.models().length === 0) {
|
|
@@ -59,13 +68,16 @@ function assertOptions(options) {
|
|
|
59
68
|
* engine, the capability profile, and the transcript tables this plugin now
|
|
60
69
|
* owns and migrates.
|
|
61
70
|
*
|
|
71
|
+
* Each entry is a backend this deployment actually configured. An enabled
|
|
72
|
+
* copilot needs at least one; a disabled one needs none, and a checkout with no
|
|
73
|
+
* keys registers none.
|
|
74
|
+
*
|
|
62
75
|
* @example
|
|
63
76
|
* ```typescript
|
|
64
77
|
* CopilotPlugin({
|
|
65
78
|
* providers: [
|
|
66
79
|
* { name: 'claude', provider: createAnthropicProvider(providers.claude) },
|
|
67
|
-
* { name: 'ollama', provider: createOpenAiProvider(providers.ollama) }
|
|
68
|
-
* { name: 'fake', provider: createFakeProvider() }
|
|
80
|
+
* { name: 'ollama', provider: createOpenAiProvider(providers.ollama) }
|
|
69
81
|
* ],
|
|
70
82
|
* config: config.plugins.copilot
|
|
71
83
|
* });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orthacms/copilot-server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "@orthacms/copilot-server — part of Ortha CMS.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/ortha-source/ortha-cms/tree/main/packages/copilot/server",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@nestjs/common": "^11.0.0",
|
|
30
30
|
"@nestjs/swagger": "^11.4.6",
|
|
31
|
-
"@orthacms/bootstrap-server": "^0.4.
|
|
32
|
-
"@orthacms/copilot-domain": "^0.4.
|
|
33
|
-
"@orthacms/database": "^0.4.
|
|
34
|
-
"@orthacms/identity-server": "^0.4.
|
|
35
|
-
"@orthacms/tools-server": "^0.4.
|
|
36
|
-
"@orthacms/workspaces-server": "^0.4.
|
|
31
|
+
"@orthacms/bootstrap-server": "^0.4.3",
|
|
32
|
+
"@orthacms/copilot-domain": "^0.4.3",
|
|
33
|
+
"@orthacms/database": "^0.4.3",
|
|
34
|
+
"@orthacms/identity-server": "^0.4.3",
|
|
35
|
+
"@orthacms/tools-server": "^0.4.3",
|
|
36
|
+
"@orthacms/workspaces-server": "^0.4.3",
|
|
37
37
|
"class-transformer": "^0.5.1",
|
|
38
38
|
"class-validator": "^0.15.1",
|
|
39
39
|
"drizzle-orm": "^0.45.0",
|