@coffer-org/plugin-claude-agent 2.1.0 → 2.2.0

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/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { definePlugin } from '@coffer-org/sdk/plugin';
2
2
  import { defineSettings } from '@coffer-org/sdk/settings';
3
3
  import { field } from '@coffer-org/sdk/fields';
4
+ import { CLAUDE_MODELS, EFFORT_LEVELS } from "./models.js";
4
5
  export default definePlugin({
5
6
  id: 'claude-agent',
6
7
  version: '1.0.0',
@@ -8,31 +9,63 @@ export default definePlugin({
8
9
  settings: defineSettings({
9
10
  label: 'claude-agent.settings.label',
10
11
  fields: [
11
- field.select({
12
- key: 'auth_mode',
13
- label: 'claude-agent.settings.auth_mode',
14
- default: 'subscription',
15
- options: [
16
- { value: 'subscription', title: 'claude-agent.settings.auth_mode_subscription' },
17
- { value: 'api_key', title: 'claude-agent.settings.auth_mode_api_key' },
12
+ field.group({
13
+ label: 'claude-agent.settings.groups.runtime',
14
+ icon: 'lucide:bot',
15
+ fields: [
16
+ field.select({
17
+ key: 'auth_mode',
18
+ label: 'claude-agent.settings.auth_mode',
19
+ default: 'subscription',
20
+ options: [
21
+ { value: 'subscription', title: 'claude-agent.settings.auth_mode_subscription' },
22
+ { value: 'api_key', title: 'claude-agent.settings.auth_mode_api_key' },
23
+ ],
24
+ }),
25
+ field.password({
26
+ key: 'anthropic_api_key',
27
+ label: 'claude-agent.settings.anthropic_api_key',
28
+ view: { hidden: { auth_mode: { $ne: 'api_key' } } },
29
+ }),
30
+ field.select({
31
+ key: 'claude_model',
32
+ label: 'claude-agent.settings.claude_model',
33
+ default: 'haiku',
34
+ options: CLAUDE_MODELS.map((m) => ({ value: m.value, title: m.title })),
35
+ }),
36
+ field.select({
37
+ key: 'effort',
38
+ label: 'claude-agent.settings.effort',
39
+ default: '',
40
+ options: [
41
+ { value: '', title: 'claude-agent.settings.effort_default' },
42
+ ...EFFORT_LEVELS.map((v) => ({ value: v, title: v })),
43
+ ],
44
+ }),
45
+ field.boolean({ key: 'thinking_enabled', label: 'claude-agent.settings.thinking_enabled', default: false }),
46
+ field.boolean({ key: 'skip_permissions', label: 'claude-agent.settings.skip_permissions', default: true }),
47
+ field.int({ key: 'response_timeout', label: 'claude-agent.settings.response_timeout', default: 600 }),
18
48
  ],
19
49
  }),
20
- field.password({
21
- key: 'anthropic_api_key',
22
- label: 'claude-agent.settings.anthropic_api_key',
23
- view: { hidden: { auth_mode: { $ne: 'api_key' } } },
50
+ field.group({
51
+ label: 'claude-agent.settings.groups.rag',
52
+ icon: 'lucide:search',
53
+ fields: [
54
+ field.boolean({ key: 'rag_enabled', label: 'claude-agent.settings.rag_enabled', default: true }),
55
+ field.password({ key: 'openai_api_key', label: 'claude-agent.settings.openai_api_key' }),
56
+ field.int({ key: 'rag_top_k', label: 'claude-agent.settings.rag_top_k', default: 5, view: { hidden: true } }),
57
+ ],
58
+ }),
59
+ field.group({
60
+ label: 'claude-agent.settings.groups.langfuse',
61
+ icon: 'lucide:activity',
62
+ fields: [
63
+ field.boolean({ key: 'tracing_enabled', label: 'claude-agent.settings.tracing_enabled' }),
64
+ field.string({ key: 'langfuse_base_url', label: 'claude-agent.settings.langfuse_base_url' }),
65
+ field.password({ key: 'langfuse_public_key', label: 'claude-agent.settings.langfuse_public_key' }),
66
+ field.password({ key: 'langfuse_secret_key', label: 'claude-agent.settings.langfuse_secret_key' }),
67
+ ],
24
68
  }),
25
- field.string({ key: 'claude_model', label: 'claude-agent.settings.claude_model', default: 'haiku' }),
26
- field.boolean({ key: 'skip_permissions', label: 'claude-agent.settings.skip_permissions', default: true }),
27
- field.int({ key: 'response_timeout', label: 'claude-agent.settings.response_timeout', default: 600 }),
28
- field.boolean({ key: 'rag_enabled', label: 'claude-agent.settings.rag_enabled', default: true }),
29
- field.int({ key: 'rag_top_k', label: 'claude-agent.settings.rag_top_k', default: 5 }),
30
- field.boolean({ key: 'thinking_enabled', label: 'claude-agent.settings.thinking_enabled', default: false }),
31
- field.password({ key: 'openai_api_key', label: 'claude-agent.settings.openai_api_key' }),
32
- field.password({ key: 'langfuse_public_key', label: 'claude-agent.settings.langfuse_public_key' }),
33
- field.password({ key: 'langfuse_secret_key', label: 'claude-agent.settings.langfuse_secret_key' }),
34
- field.string({ key: 'langfuse_base_url', label: 'claude-agent.settings.langfuse_base_url' }),
35
- field.boolean({ key: 'tracing_enabled', label: 'claude-agent.settings.tracing_enabled' }),
36
69
  ],
37
70
  }),
38
71
  });
@@ -0,0 +1,23 @@
1
+ export declare const CLAUDE_MODELS: readonly [{
2
+ readonly value: "haiku";
3
+ readonly id: "claude-haiku-4-5";
4
+ readonly title: "Haiku 4.5 — найшвидша";
5
+ }, {
6
+ readonly value: "sonnet";
7
+ readonly id: "claude-sonnet-5";
8
+ readonly title: "Sonnet 5";
9
+ }, {
10
+ readonly value: "opus";
11
+ readonly id: "claude-opus-4-8";
12
+ readonly title: "Opus 4.8";
13
+ }, {
14
+ readonly value: "claude-opus-5";
15
+ readonly id: "claude-opus-5";
16
+ readonly title: "Opus 5";
17
+ }, {
18
+ readonly value: "claude-fable-5";
19
+ readonly id: "claude-fable-5";
20
+ readonly title: "Fable 5 — найдорожча";
21
+ }];
22
+ export declare const EFFORT_LEVELS: readonly ["low", "medium", "high", "xhigh", "max"];
23
+ export type Effort = (typeof EFFORT_LEVELS)[number];
package/dist/models.js ADDED
@@ -0,0 +1,8 @@
1
+ export const CLAUDE_MODELS = [
2
+ { value: 'haiku', id: 'claude-haiku-4-5', title: 'Haiku 4.5 — найшвидша' },
3
+ { value: 'sonnet', id: 'claude-sonnet-5', title: 'Sonnet 5' },
4
+ { value: 'opus', id: 'claude-opus-4-8', title: 'Opus 4.8' },
5
+ { value: 'claude-opus-5', id: 'claude-opus-5', title: 'Opus 5' },
6
+ { value: 'claude-fable-5', id: 'claude-fable-5', title: 'Fable 5 — найдорожча' },
7
+ ];
8
+ export const EFFORT_LEVELS = ['low', 'medium', 'high', 'xhigh', 'max'];
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import Anthropic from '@anthropic-ai/sdk';
3
- import { loadAgentConfig, modelId } from "./config.js";
3
+ import { effortParam, loadAgentConfig, modelId } from "./config.js";
4
4
  import { makeAgentTools } from "./coffer.js";
5
5
  import { buildDomainSections } from '@coffer-org/server/mcp-tools';
6
6
  import { isTracing, flushTracing, langfuseFactory, TurnTracer } from "./tracing.js";
@@ -155,6 +155,7 @@ export async function runAgent(request, deps = {}) {
155
155
  }
156
156
  }
157
157
  const thinking = thinkingParam(cfg.thinkingEnabled);
158
+ const outputConfig = effortParam(cfg.effort, modelId(cfg.claudeModel));
158
159
  if (cfg.thinkingEnabled)
159
160
  log.info(`extended thinking ON (${modelId(cfg.claudeModel)})`);
160
161
  let tokensIn = null;
@@ -171,6 +172,7 @@ export async function runAgent(request, deps = {}) {
171
172
  messages,
172
173
  tools: tools,
173
174
  ...(thinking ? { thinking } : {}),
175
+ ...(outputConfig ? { output_config: outputConfig } : {}),
174
176
  }, { signal: ac.signal });
175
177
  stream.on('text', (delta) => {
176
178
  streamed = appendTextDelta(streamed, delta);
@@ -1,8 +1,15 @@
1
1
  export declare const APP_ROOT: string;
2
2
  export declare const PLUGIN_ROOT: string;
3
+ import { CLAUDE_MODELS, EFFORT_LEVELS, type Effort } from '../models.ts';
4
+ export { CLAUDE_MODELS, EFFORT_LEVELS };
5
+ export type { Effort };
3
6
  export type AuthMode = 'subscription' | 'api_key';
4
7
  export declare function supportsAdaptiveThinking(model: string): boolean;
5
8
  export declare function modelId(alias: string): string;
9
+ export declare function supportsEffort(model: string): boolean;
10
+ export declare function effortParam(effort: string, model: string): {
11
+ effort: Effort;
12
+ } | undefined;
6
13
  export interface AgentConfig {
7
14
  authMode: AuthMode;
8
15
  anthropicApiKey: string;
@@ -12,6 +19,7 @@ export interface AgentConfig {
12
19
  ragEnabled: boolean;
13
20
  ragTopK: number;
14
21
  thinkingEnabled: boolean;
22
+ effort: string;
15
23
  embeddingApiKey: string;
16
24
  langfusePublicKey: string;
17
25
  langfuseSecretKey: string;
@@ -4,6 +4,8 @@ import { fileURLToPath } from 'node:url';
4
4
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
5
5
  export const APP_ROOT = path.resolve(__dirname, '../../../..');
6
6
  export const PLUGIN_ROOT = path.resolve(__dirname, '../..');
7
+ import { CLAUDE_MODELS, EFFORT_LEVELS } from "../models.js";
8
+ export { CLAUDE_MODELS, EFFORT_LEVELS };
7
9
  const ADAPTIVE_THINKING_MODELS = [
8
10
  'claude-opus-5', 'claude-opus-4-8', 'claude-opus-4-7', 'claude-opus-4-6',
9
11
  'claude-sonnet-5', 'claude-sonnet-4-6',
@@ -13,12 +15,18 @@ export function supportsAdaptiveThinking(model) {
13
15
  return ADAPTIVE_THINKING_MODELS.some((m) => model === m || model.startsWith(`${m}-`));
14
16
  }
15
17
  export function modelId(alias) {
16
- const map = {
17
- haiku: 'claude-haiku-4-5',
18
- sonnet: 'claude-sonnet-5',
19
- opus: 'claude-opus-4-8',
20
- };
21
- return map[alias] ?? (alias.startsWith('claude-') ? alias : 'claude-opus-4-8');
18
+ const known = CLAUDE_MODELS.find((m) => m.value === alias);
19
+ if (known)
20
+ return known.id;
21
+ return alias.startsWith('claude-') ? alias : 'claude-opus-4-8';
22
+ }
23
+ export function supportsEffort(model) {
24
+ return supportsAdaptiveThinking(model);
25
+ }
26
+ export function effortParam(effort, model) {
27
+ return EFFORT_LEVELS.includes(effort) && supportsEffort(model)
28
+ ? { effort: effort }
29
+ : undefined;
22
30
  }
23
31
  export function loadAgentConfig(opts = {}) {
24
32
  const env = opts.env ?? process.env;
@@ -32,9 +40,10 @@ export function loadAgentConfig(opts = {}) {
32
40
  skipPermissions: db.skip_permissions !== false,
33
41
  responseTimeout: Math.max(60, Number(env.AGENT_RESPONSE_TIMEOUT ?? db.response_timeout ?? 600) || 600),
34
42
  ragEnabled: db.rag_enabled !== false,
35
- ragTopK: Number(env.AGENT_RAG_TOP_K ?? db.rag_top_k ?? 5) || 5,
43
+ ragTopK: 5,
36
44
  thinkingEnabled: (env.AGENT_THINKING_ENABLED ?? String(db.thinking_enabled)) === 'true'
37
45
  && supportsAdaptiveThinking(modelId(claudeModel)),
46
+ effort: String(env.AGENT_EFFORT ?? db.effort ?? ''),
38
47
  embeddingApiKey: env.OPENAI_API_KEY ?? db.openai_api_key ?? '',
39
48
  langfusePublicKey: env.LANGFUSE_PUBLIC_KEY ?? db.langfuse_public_key ?? '',
40
49
  langfuseSecretKey: env.LANGFUSE_SECRET_KEY ?? db.langfuse_secret_key ?? '',
package/dist/schema.js CHANGED
@@ -7084,72 +7084,139 @@ var src_default = definePlugin({
7084
7084
  settings: defineSettings({
7085
7085
  label: "claude-agent.settings.label",
7086
7086
  fields: [
7087
- field.select({
7088
- key: "auth_mode",
7089
- label: "claude-agent.settings.auth_mode",
7090
- default: "subscription",
7091
- options: [{
7092
- value: "subscription",
7093
- title: "claude-agent.settings.auth_mode_subscription"
7094
- }, {
7095
- value: "api_key",
7096
- title: "claude-agent.settings.auth_mode_api_key"
7097
- }]
7098
- }),
7099
- field.password({
7100
- key: "anthropic_api_key",
7101
- label: "claude-agent.settings.anthropic_api_key",
7102
- view: { hidden: { auth_mode: { $ne: "api_key" } } }
7103
- }),
7104
- field.string({
7105
- key: "claude_model",
7106
- label: "claude-agent.settings.claude_model",
7107
- default: "haiku"
7108
- }),
7109
- field.boolean({
7110
- key: "skip_permissions",
7111
- label: "claude-agent.settings.skip_permissions",
7112
- default: true
7113
- }),
7114
- field.int({
7115
- key: "response_timeout",
7116
- label: "claude-agent.settings.response_timeout",
7117
- default: 600
7118
- }),
7119
- field.boolean({
7120
- key: "rag_enabled",
7121
- label: "claude-agent.settings.rag_enabled",
7122
- default: true
7123
- }),
7124
- field.int({
7125
- key: "rag_top_k",
7126
- label: "claude-agent.settings.rag_top_k",
7127
- default: 5
7128
- }),
7129
- field.boolean({
7130
- key: "thinking_enabled",
7131
- label: "claude-agent.settings.thinking_enabled",
7132
- default: false
7133
- }),
7134
- field.password({
7135
- key: "openai_api_key",
7136
- label: "claude-agent.settings.openai_api_key"
7137
- }),
7138
- field.password({
7139
- key: "langfuse_public_key",
7140
- label: "claude-agent.settings.langfuse_public_key"
7141
- }),
7142
- field.password({
7143
- key: "langfuse_secret_key",
7144
- label: "claude-agent.settings.langfuse_secret_key"
7087
+ field.group({
7088
+ label: "claude-agent.settings.groups.runtime",
7089
+ icon: "lucide:bot",
7090
+ fields: [
7091
+ field.select({
7092
+ key: "auth_mode",
7093
+ label: "claude-agent.settings.auth_mode",
7094
+ default: "subscription",
7095
+ options: [{
7096
+ value: "subscription",
7097
+ title: "claude-agent.settings.auth_mode_subscription"
7098
+ }, {
7099
+ value: "api_key",
7100
+ title: "claude-agent.settings.auth_mode_api_key"
7101
+ }]
7102
+ }),
7103
+ field.password({
7104
+ key: "anthropic_api_key",
7105
+ label: "claude-agent.settings.anthropic_api_key",
7106
+ view: { hidden: { auth_mode: { $ne: "api_key" } } }
7107
+ }),
7108
+ field.select({
7109
+ key: "claude_model",
7110
+ label: "claude-agent.settings.claude_model",
7111
+ default: "haiku",
7112
+ options: [
7113
+ {
7114
+ value: "haiku",
7115
+ id: "claude-haiku-4-5",
7116
+ title: "Haiku 4.5 — найшвидша"
7117
+ },
7118
+ {
7119
+ value: "sonnet",
7120
+ id: "claude-sonnet-5",
7121
+ title: "Sonnet 5"
7122
+ },
7123
+ {
7124
+ value: "opus",
7125
+ id: "claude-opus-4-8",
7126
+ title: "Opus 4.8"
7127
+ },
7128
+ {
7129
+ value: "claude-opus-5",
7130
+ id: "claude-opus-5",
7131
+ title: "Opus 5"
7132
+ },
7133
+ {
7134
+ value: "claude-fable-5",
7135
+ id: "claude-fable-5",
7136
+ title: "Fable 5 — найдорожча"
7137
+ }
7138
+ ].map((m) => ({
7139
+ value: m.value,
7140
+ title: m.title
7141
+ }))
7142
+ }),
7143
+ field.select({
7144
+ key: "effort",
7145
+ label: "claude-agent.settings.effort",
7146
+ default: "",
7147
+ options: [{
7148
+ value: "",
7149
+ title: "claude-agent.settings.effort_default"
7150
+ }, ...[
7151
+ "low",
7152
+ "medium",
7153
+ "high",
7154
+ "xhigh",
7155
+ "max"
7156
+ ].map((v) => ({
7157
+ value: v,
7158
+ title: v
7159
+ }))]
7160
+ }),
7161
+ field.boolean({
7162
+ key: "thinking_enabled",
7163
+ label: "claude-agent.settings.thinking_enabled",
7164
+ default: false
7165
+ }),
7166
+ field.boolean({
7167
+ key: "skip_permissions",
7168
+ label: "claude-agent.settings.skip_permissions",
7169
+ default: true
7170
+ }),
7171
+ field.int({
7172
+ key: "response_timeout",
7173
+ label: "claude-agent.settings.response_timeout",
7174
+ default: 600
7175
+ })
7176
+ ]
7145
7177
  }),
7146
- field.string({
7147
- key: "langfuse_base_url",
7148
- label: "claude-agent.settings.langfuse_base_url"
7178
+ field.group({
7179
+ label: "claude-agent.settings.groups.rag",
7180
+ icon: "lucide:search",
7181
+ fields: [
7182
+ field.boolean({
7183
+ key: "rag_enabled",
7184
+ label: "claude-agent.settings.rag_enabled",
7185
+ default: true
7186
+ }),
7187
+ field.password({
7188
+ key: "openai_api_key",
7189
+ label: "claude-agent.settings.openai_api_key"
7190
+ }),
7191
+ field.int({
7192
+ key: "rag_top_k",
7193
+ label: "claude-agent.settings.rag_top_k",
7194
+ default: 5,
7195
+ view: { hidden: true }
7196
+ })
7197
+ ]
7149
7198
  }),
7150
- field.boolean({
7151
- key: "tracing_enabled",
7152
- label: "claude-agent.settings.tracing_enabled"
7199
+ field.group({
7200
+ label: "claude-agent.settings.groups.langfuse",
7201
+ icon: "lucide:activity",
7202
+ fields: [
7203
+ field.boolean({
7204
+ key: "tracing_enabled",
7205
+ label: "claude-agent.settings.tracing_enabled"
7206
+ }),
7207
+ field.string({
7208
+ key: "langfuse_base_url",
7209
+ label: "claude-agent.settings.langfuse_base_url"
7210
+ }),
7211
+ field.password({
7212
+ key: "langfuse_public_key",
7213
+ label: "claude-agent.settings.langfuse_public_key"
7214
+ }),
7215
+ field.password({
7216
+ key: "langfuse_secret_key",
7217
+ label: "claude-agent.settings.langfuse_secret_key"
7218
+ })
7219
+ ]
7153
7220
  })
7154
7221
  ]
7155
7222
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffer-org/plugin-claude-agent",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24"
@@ -26,9 +26,9 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@anthropic-ai/sdk": "^0.111.0",
29
- "@coffer-org/mcp": "^2.1.0",
29
+ "@coffer-org/mcp": "^2.2.0",
30
30
  "@coffer-org/sdk": "^2.0.0",
31
- "@coffer-org/server": "^2.1.0",
31
+ "@coffer-org/server": "^2.1.1",
32
32
  "@langfuse/otel": "^4.6.1",
33
33
  "@langfuse/tracing": "^4.6.1",
34
34
  "@opentelemetry/sdk-trace-node": "^2.8.0",