@coffer-org/server 7.1.0 → 7.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/background-scheduler.d.ts +1 -0
- package/dist/background-scheduler.js +2 -1
- package/dist/mcp-contract/schema.d.ts +34 -1
- package/dist/mcp-contract/schema.js +32 -9
- package/dist/mcp-contract/tools.js +3 -1
- package/dist/mcp-tools.d.ts +3 -2
- package/dist/mcp-tools.js +11 -7
- package/dist/orchestrator/index.d.ts +1 -0
- package/dist/orchestrator/index.js +1 -0
- package/dist/orchestrator/types.d.ts +5 -0
- package/package.json +2 -2
|
@@ -17,6 +17,7 @@ export interface BackgroundScheduler {
|
|
|
17
17
|
start(): void;
|
|
18
18
|
stop(): void;
|
|
19
19
|
}
|
|
20
|
+
export declare const DEFAULT_TASK_TIMEOUT_MS = 600000;
|
|
20
21
|
export declare function makeScheduler(opts?: SchedulerOpts): BackgroundScheduler;
|
|
21
22
|
export declare function startScheduler(tasks: BackgroundTask[], opts?: SchedulerOpts): void;
|
|
22
23
|
export declare function stopScheduler(): void;
|
|
@@ -6,10 +6,11 @@ const defaultSetTimer = (cb, ms) => {
|
|
|
6
6
|
t.unref();
|
|
7
7
|
return t;
|
|
8
8
|
};
|
|
9
|
+
export const DEFAULT_TASK_TIMEOUT_MS = 600_000;
|
|
9
10
|
export function makeScheduler(opts = {}) {
|
|
10
11
|
const startupDelayMs = opts.startupDelayMs ?? (Number(process.env['BG_STARTUP_DELAY_MS']) || 600_000);
|
|
11
12
|
const gapMs = opts.gapMs ?? (Number(process.env['BG_GAP_MS']) || 30_000);
|
|
12
|
-
const defaultTimeoutMs = opts.taskTimeoutMs ?? (Number(process.env['BG_TASK_TIMEOUT_MS']) ||
|
|
13
|
+
const defaultTimeoutMs = opts.taskTimeoutMs ?? (Number(process.env['BG_TASK_TIMEOUT_MS']) || DEFAULT_TASK_TIMEOUT_MS);
|
|
13
14
|
const setTimer = opts.setTimer ?? defaultSetTimer;
|
|
14
15
|
const clearTimer = opts.clearTimer ?? ((h) => clearTimeout(h));
|
|
15
16
|
const tasks = [];
|
|
@@ -1,4 +1,30 @@
|
|
|
1
1
|
import type { LocaleResolver } from '../locale-registry.ts';
|
|
2
|
+
import { type AgentMeta } from '@coffer-org/sdk/library';
|
|
3
|
+
import type { Condition } from '@coffer-org/sdk/condition';
|
|
4
|
+
interface ShelfClient {
|
|
5
|
+
shelf: string;
|
|
6
|
+
library: string;
|
|
7
|
+
label: string;
|
|
8
|
+
agent?: string;
|
|
9
|
+
standalone?: boolean;
|
|
10
|
+
fields: unknown[];
|
|
11
|
+
}
|
|
12
|
+
interface ExtendClient {
|
|
13
|
+
id: string;
|
|
14
|
+
attachTo: {
|
|
15
|
+
library: string;
|
|
16
|
+
shelf?: string;
|
|
17
|
+
}[];
|
|
18
|
+
showWhen?: Condition;
|
|
19
|
+
agent?: AgentMeta | string;
|
|
20
|
+
}
|
|
21
|
+
interface LibraryClient {
|
|
22
|
+
id: string;
|
|
23
|
+
label: string;
|
|
24
|
+
agent?: AgentMeta | string;
|
|
25
|
+
extends?: ExtendClient[];
|
|
26
|
+
shelves: ShelfClient[];
|
|
27
|
+
}
|
|
2
28
|
export interface ShelfIndexEntry {
|
|
3
29
|
library: string;
|
|
4
30
|
libraryLabel: string;
|
|
@@ -25,13 +51,20 @@ export declare const FILE_WRITE_HINT: string;
|
|
|
25
51
|
export declare const SOURCE_WRITE_HINT: string;
|
|
26
52
|
export declare const DERIVED_WRITE_HINT: string;
|
|
27
53
|
export declare const serverOwnedPartsHint: (roles: string[]) => string;
|
|
54
|
+
export interface OperatingRule {
|
|
55
|
+
source: string;
|
|
56
|
+
when?: string;
|
|
57
|
+
text: string;
|
|
58
|
+
}
|
|
28
59
|
export interface ShelfDescription {
|
|
29
60
|
library: string;
|
|
30
61
|
shelf: string;
|
|
31
62
|
label: string;
|
|
32
63
|
agent?: string;
|
|
64
|
+
operatingRules?: OperatingRule[];
|
|
33
65
|
fields: FieldInfo[];
|
|
34
66
|
}
|
|
67
|
+
export declare function collectOperatingRules(lib: LibraryClient, shelf: string): OperatingRule[];
|
|
35
68
|
interface SchemaClient {
|
|
36
69
|
getSchema(): Promise<unknown>;
|
|
37
70
|
}
|
|
@@ -46,6 +79,6 @@ export declare class SchemaCache {
|
|
|
46
79
|
private load;
|
|
47
80
|
index(): Promise<ShelfIndexEntry[]>;
|
|
48
81
|
describeShelf(library: string, shelf: string): Promise<ShelfDescription>;
|
|
49
|
-
private
|
|
82
|
+
private locate;
|
|
50
83
|
}
|
|
51
84
|
export {};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { normalizeAgentMeta } from '@coffer-org/sdk/library';
|
|
2
|
+
import { extendMatches } from '@coffer-org/sdk/extend';
|
|
3
|
+
import { describeCondition } from '@coffer-org/sdk/condition';
|
|
1
4
|
export const FILE_WRITE_HINT = 'Uploaded file only: {"name":"<filename returned by POST /api/upload>"} ' +
|
|
2
5
|
'(or an array of those when the field is multiple). ' +
|
|
3
6
|
'A remote URL is rejected — the server stores files, not links. ' +
|
|
@@ -13,6 +16,22 @@ export const DERIVED_WRITE_HINT = 'Read-only — the server recomputes this fiel
|
|
|
13
16
|
export const serverOwnedPartsHint = (roles) => `Partly read-only — the server owns ${roles.map((r) => `\`${r}\``).join(', ')} in this value and ` +
|
|
14
17
|
`computes ${roles.length > 1 ? 'them' : 'it'} on every write. Send the other roles only; anything ` +
|
|
15
18
|
`sent for these is discarded, and a read returns the server's value.`;
|
|
19
|
+
export function collectOperatingRules(lib, shelf) {
|
|
20
|
+
const out = [];
|
|
21
|
+
const libAgent = normalizeAgentMeta(lib.agent);
|
|
22
|
+
if (libAgent?.instructions)
|
|
23
|
+
out.push({ source: lib.id, text: libAgent.instructions });
|
|
24
|
+
for (const e of lib.extends ?? []) {
|
|
25
|
+
if (!extendMatches(e, lib.id, shelf))
|
|
26
|
+
continue;
|
|
27
|
+
const meta = normalizeAgentMeta(e.agent);
|
|
28
|
+
if (!meta?.instructions)
|
|
29
|
+
continue;
|
|
30
|
+
const when = describeCondition(e.showWhen, (f) => f).join(' and ');
|
|
31
|
+
out.push({ source: e.id, ...(when ? { when } : {}), text: meta.instructions });
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
16
35
|
function serverOwnedRoles(t) {
|
|
17
36
|
const parts = t.parts ?? [];
|
|
18
37
|
return parts.filter((p) => p.mode === 'computedStored').map((p) => p.role);
|
|
@@ -89,20 +108,24 @@ export class SchemaCache {
|
|
|
89
108
|
})));
|
|
90
109
|
}
|
|
91
110
|
async describeShelf(library, shelf) {
|
|
92
|
-
let
|
|
93
|
-
if (!
|
|
94
|
-
|
|
95
|
-
if (!
|
|
111
|
+
let at = this.locate(await this.load(), library, shelf);
|
|
112
|
+
if (!at)
|
|
113
|
+
at = this.locate(await this.load(true), library, shelf);
|
|
114
|
+
if (!at)
|
|
96
115
|
throw new Error(`unknown_shelf ${library}/${shelf}`);
|
|
116
|
+
const rules = collectOperatingRules(at.lib, shelf);
|
|
97
117
|
return {
|
|
98
118
|
library,
|
|
99
119
|
shelf,
|
|
100
|
-
label: this.display(m.label, m.shelf),
|
|
101
|
-
...(m.agent ? { agent: m.agent } : {}),
|
|
102
|
-
|
|
120
|
+
label: this.display(at.m.label, at.m.shelf),
|
|
121
|
+
...(at.m.agent ? { agent: at.m.agent } : {}),
|
|
122
|
+
...(rules.length ? { operatingRules: rules } : {}),
|
|
123
|
+
fields: flattenFields(at.m.fields),
|
|
103
124
|
};
|
|
104
125
|
}
|
|
105
|
-
|
|
106
|
-
|
|
126
|
+
locate(libraries, library, shelf) {
|
|
127
|
+
const lib = libraries.find((v) => v.id === library);
|
|
128
|
+
const m = lib?.shelves.find((s) => s.shelf === shelf);
|
|
129
|
+
return lib && m ? { lib, m } : undefined;
|
|
107
130
|
}
|
|
108
131
|
}
|
|
@@ -53,7 +53,9 @@ export function buildTools(client, cache, locales) {
|
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
name: 'describe_shelf',
|
|
56
|
-
description: 'Detailed shelf schema: the shelf note (agent),
|
|
56
|
+
description: 'Detailed shelf schema: the shelf note (agent), the operating rules that govern writing here ' +
|
|
57
|
+
'(operatingRules — from the library and from any extra field-set attached to this shelf, each ' +
|
|
58
|
+
'with the condition it applies under), then fields with kind/prim/required, relation/options, and ' +
|
|
57
59
|
'a per-field note (agent) saying what that field means. A collection is one entry with multiple:true and its ' +
|
|
58
60
|
'row shape in fields[]. A field with derived:true is computed by the server and rejects writes — omit it when ' +
|
|
59
61
|
'writing. Call BEFORE create_record/update_record.',
|
package/dist/mcp-tools.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { type ToolResult } from './mcp-contract/tools.ts';
|
|
|
4
4
|
import { type LocaleResolver } from './locale-registry.ts';
|
|
5
5
|
import { type AuthRole, type PluginHooks } from './plugin-hooks.ts';
|
|
6
6
|
import { type Condition } from '@coffer-org/sdk/condition';
|
|
7
|
+
import { type AgentMeta } from '@coffer-org/sdk/library';
|
|
7
8
|
import { type RagHit } from './rag-search.ts';
|
|
8
9
|
export interface McpToolDef {
|
|
9
10
|
server: string;
|
|
@@ -58,12 +59,12 @@ export declare function collectLibraryPurposes(reg?: {
|
|
|
58
59
|
meta: {
|
|
59
60
|
id: string;
|
|
60
61
|
label?: string;
|
|
61
|
-
agent?: string;
|
|
62
|
+
agent?: AgentMeta | string;
|
|
62
63
|
};
|
|
63
64
|
}[];
|
|
64
65
|
extends_: {
|
|
65
66
|
id: string;
|
|
66
|
-
agent?: string;
|
|
67
|
+
agent?: AgentMeta | string;
|
|
67
68
|
showWhen?: Condition;
|
|
68
69
|
attachTo: {
|
|
69
70
|
library: string;
|
package/dist/mcp-tools.js
CHANGED
|
@@ -10,6 +10,7 @@ import { pluginHooks, pluginCtx } from "./plugin-hooks.js";
|
|
|
10
10
|
import { getActiveRegistry } from "./registry-context.js";
|
|
11
11
|
import { countTargetsFor, recordCounts } from "./counts.js";
|
|
12
12
|
import { describeCondition } from '@coffer-org/sdk/condition';
|
|
13
|
+
import { normalizeAgentMeta } from '@coffer-org/sdk/library';
|
|
13
14
|
import { getEm } from "./db.js";
|
|
14
15
|
import { getPluginSettings } from "./plugin-runtime.js";
|
|
15
16
|
import { configuredPublicUrl } from "./public-url.js";
|
|
@@ -296,16 +297,19 @@ export function collectLibraryPurposes(reg, locales) {
|
|
|
296
297
|
if (!registry)
|
|
297
298
|
return [];
|
|
298
299
|
return registry.libraries
|
|
299
|
-
.filter((v) => v.meta.agent)
|
|
300
|
+
.filter((v) => normalizeAgentMeta(v.meta.agent)?.description)
|
|
300
301
|
.map((v) => ({
|
|
301
302
|
id: v.meta.id,
|
|
302
303
|
name: (v.meta.label ? locales?.resolve(v.meta.label) : undefined) ?? v.meta.id,
|
|
303
|
-
agent: v.meta.agent,
|
|
304
|
-
extends: registry.extends_.flatMap((e) =>
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
304
|
+
agent: normalizeAgentMeta(v.meta.agent).description,
|
|
305
|
+
extends: registry.extends_.flatMap((e) => {
|
|
306
|
+
const meta = normalizeAgentMeta(e.agent);
|
|
307
|
+
return meta?.description
|
|
308
|
+
? e.attachTo
|
|
309
|
+
.filter((a) => a.library === v.meta.id)
|
|
310
|
+
.map((a) => ({ id: e.id, shelf: a.shelf, agent: meta.description, showWhen: e.showWhen }))
|
|
311
|
+
: [];
|
|
312
|
+
}),
|
|
309
313
|
}));
|
|
310
314
|
}
|
|
311
315
|
export async function siteSection(siteUrl) {
|
|
@@ -17,6 +17,7 @@ export { isSenderAllowed } from './allow.ts';
|
|
|
17
17
|
export { makeLiveChannel, plainRender } from './live-message.ts';
|
|
18
18
|
export type { LiveChannelOps, LiveChannelOpts, RenderFn } from './live-message.ts';
|
|
19
19
|
export { chunk } from './format.ts';
|
|
20
|
+
export { DEFAULT_TASK_TIMEOUT_MS } from '../background-scheduler.ts';
|
|
20
21
|
export type { Connector, IncomingConversation, GatePolicy, ReplyContext, ReplyPayload, ReplyChannel, AttachmentRef, AttachmentMaterializer, AgentToolDefinition, AgentToolProvider, ConvMessage, AgentRequest, AgentResult, AgentRuntime, AgentCapabilities, AgentPreset, AgentDescriptor, ConnectorRegistration, AgentToolContentBlock, AgentToolContentResult, } from './types.ts';
|
|
21
22
|
export declare function startOrchestrator(): void;
|
|
22
23
|
export declare function stopOrchestrator(): void;
|
|
@@ -20,6 +20,7 @@ export { isSenderAllowed } from "./allow.js";
|
|
|
20
20
|
import { carryLegacyState } from "./allow.js";
|
|
21
21
|
export { makeLiveChannel, plainRender } from "./live-message.js";
|
|
22
22
|
export { chunk } from "./format.js";
|
|
23
|
+
export { DEFAULT_TASK_TIMEOUT_MS } from "../background-scheduler.js";
|
|
23
24
|
let db;
|
|
24
25
|
const STARTERS_CHECK_INTERVAL_MS = 10 * 60_000;
|
|
25
26
|
function runStartersRefresh() {
|
|
@@ -60,11 +60,16 @@ export interface AgentDescriptor {
|
|
|
60
60
|
title: string;
|
|
61
61
|
presets: AgentPreset[];
|
|
62
62
|
}
|
|
63
|
+
export interface AgentBudget {
|
|
64
|
+
responseTimeout?: number;
|
|
65
|
+
toolRounds?: number;
|
|
66
|
+
}
|
|
63
67
|
export interface AgentRequest {
|
|
64
68
|
system: string;
|
|
65
69
|
messages: ConvMessage[];
|
|
66
70
|
toolProvider?: AgentToolProvider;
|
|
67
71
|
presetId?: string;
|
|
72
|
+
budget?: AgentBudget;
|
|
68
73
|
onDelta?: (accumulated: string) => void;
|
|
69
74
|
onReasoning?: (accumulated: string) => void;
|
|
70
75
|
onSegment?: () => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coffer-org/server",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=24"
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"postpack": "node ../../scripts/swap-exports.mjs src"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@coffer-org/sdk": "^7.
|
|
39
|
+
"@coffer-org/sdk": "^7.2.0",
|
|
40
40
|
"@extractus/oembed-extractor": "^4.1.0",
|
|
41
41
|
"@fastify/cors": "^11.2.0",
|
|
42
42
|
"@fastify/multipart": "^10.0.0",
|