@things-factory/ai-assistant 10.1.154 → 10.1.155
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/client/bootstrap.ts +27 -0
- package/client/components/assistant-chat.ts +229 -178
- package/client/components/assistant-dock.ts +53 -48
- package/client/components/assistant-session-manager.ts +82 -100
- package/client/components/assistant-session-toolbar.ts +11 -3
- package/client/components/chat-input-builder.ts +8 -2
- package/client/settings/agent-settings-model.ts +164 -0
- package/client/settings/ai-agent-setting-let.ts +684 -0
- package/client/settings/ai-usage-setting-let.ts +252 -0
- package/client/settings/usage-model.ts +46 -0
- package/client/setup-assistant-dock.ts +2 -3
- package/client/utils/agent-choice.ts +56 -0
- package/client/utils/assistant-navigation.test.ts +14 -8
- package/client/utils/assistant-navigation.ts +8 -3
- package/client/utils/composer-frame.ts +28 -2
- package/client/utils/menu-room.ts +33 -0
- package/dist-client/bootstrap.d.ts +8 -0
- package/dist-client/bootstrap.js +26 -0
- package/dist-client/bootstrap.js.map +1 -0
- package/dist-client/components/assistant-chat.d.ts +32 -4
- package/dist-client/components/assistant-chat.js +234 -175
- package/dist-client/components/assistant-chat.js.map +1 -1
- package/dist-client/components/assistant-dock.d.ts +6 -8
- package/dist-client/components/assistant-dock.js +52 -60
- package/dist-client/components/assistant-dock.js.map +1 -1
- package/dist-client/components/assistant-session-manager.d.ts +8 -7
- package/dist-client/components/assistant-session-manager.js +84 -124
- package/dist-client/components/assistant-session-manager.js.map +1 -1
- package/dist-client/components/assistant-session-toolbar.d.ts +1 -0
- package/dist-client/components/assistant-session-toolbar.js +10 -3
- package/dist-client/components/assistant-session-toolbar.js.map +1 -1
- package/dist-client/components/chat-input-builder.d.ts +4 -0
- package/dist-client/components/chat-input-builder.js +4 -2
- package/dist-client/components/chat-input-builder.js.map +1 -1
- package/dist-client/settings/agent-settings-model.d.ts +93 -0
- package/dist-client/settings/agent-settings-model.js +95 -0
- package/dist-client/settings/agent-settings-model.js.map +1 -0
- package/dist-client/settings/ai-agent-setting-let.d.ts +51 -0
- package/dist-client/settings/ai-agent-setting-let.js +672 -0
- package/dist-client/settings/ai-agent-setting-let.js.map +1 -0
- package/dist-client/settings/ai-usage-setting-let.d.ts +26 -0
- package/dist-client/settings/ai-usage-setting-let.js +276 -0
- package/dist-client/settings/ai-usage-setting-let.js.map +1 -0
- package/dist-client/settings/usage-model.d.ts +32 -0
- package/dist-client/settings/usage-model.js +25 -0
- package/dist-client/settings/usage-model.js.map +1 -0
- package/dist-client/setup-assistant-dock.d.ts +0 -1
- package/dist-client/setup-assistant-dock.js +0 -1
- package/dist-client/setup-assistant-dock.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/agent-choice.d.ts +24 -0
- package/dist-client/utils/agent-choice.js +38 -0
- package/dist-client/utils/agent-choice.js.map +1 -0
- package/dist-client/utils/assistant-navigation.d.ts +8 -3
- package/dist-client/utils/assistant-navigation.js +7 -2
- package/dist-client/utils/assistant-navigation.js.map +1 -1
- package/dist-client/utils/assistant-navigation.test.js +14 -8
- package/dist-client/utils/assistant-navigation.test.js.map +1 -1
- package/dist-client/utils/composer-frame.d.ts +23 -2
- package/dist-client/utils/composer-frame.js +20 -2
- package/dist-client/utils/composer-frame.js.map +1 -1
- package/dist-client/utils/menu-room.d.ts +13 -0
- package/dist-client/utils/menu-room.js +26 -0
- package/dist-client/utils/menu-room.js.map +1 -0
- package/dist-server/service/ai-agent-resolver.d.ts +82 -0
- package/dist-server/service/ai-agent-resolver.js +417 -0
- package/dist-server/service/ai-agent-resolver.js.map +1 -0
- package/dist-server/service/assistant-capability-resolver.d.ts +1 -1
- package/dist-server/service/assistant-capability-resolver.js +7 -7
- package/dist-server/service/assistant-capability-resolver.js.map +1 -1
- package/dist-server/service/assistant-chat-resolver.d.ts +2 -0
- package/dist-server/service/assistant-chat-resolver.js +32 -15
- package/dist-server/service/assistant-chat-resolver.js.map +1 -1
- package/dist-server/service/assistant-mode/resolve.d.ts +0 -1
- package/dist-server/service/assistant-mode/resolve.js +0 -1
- package/dist-server/service/assistant-mode/resolve.js.map +1 -1
- package/dist-server/service/assistant-mode/types.d.ts +1 -2
- package/dist-server/service/assistant-mode/types.js.map +1 -1
- package/dist-server/service/chat-session/chat-session.d.ts +2 -0
- package/dist-server/service/chat-session/chat-session.js +5 -0
- package/dist-server/service/chat-session/chat-session.js.map +1 -1
- package/dist-server/service/index.d.ts +2 -1
- package/dist-server/service/index.js +3 -0
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/testing/mode-conformance.js +0 -1
- package/dist-server/service/testing/mode-conformance.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -7
- package/server/service/ai-agent-resolver.ts +330 -0
- package/server/service/assistant-capability-resolver.ts +7 -7
- package/server/service/assistant-chat-resolver.ts +32 -24
- package/server/service/assistant-mode/resolve.test.ts +0 -2
- package/server/service/assistant-mode/resolve.ts +0 -2
- package/server/service/assistant-mode/types.ts +1 -2
- package/server/service/chat-session/chat-session.ts +5 -0
- package/server/service/index.ts +3 -0
- package/server/service/testing/mode-conformance.ts +0 -1
- package/server/tool-registry-boot-report.test.ts +2 -0
- package/test/ai-agent-settings.test.ts +123 -0
- package/test/assistant-dock.test.ts +3 -2
- package/test/assistant-session-manager.test.ts +10 -4
- package/test/assistant-session-toolbar.test.ts +8 -0
- package/test/composer-frame.test.ts +40 -2
- package/test/menu-room.test.ts +33 -0
- package/test/open-doors.test.ts +3 -1
- package/test/session-discovery.test.ts +7 -6
- package/things-factory.config.js +2 -0
- package/translations/en.json +78 -12
- package/translations/es.json +78 -12
- package/translations/ja.json +78 -12
- package/translations/ko.json +78 -12
- package/translations/ms.json +78 -12
- package/translations/zh.json +78 -12
- package/client/components/chat-triggers.test.ts +0 -72
- package/client/components/chat-triggers.ts +0 -62
- package/dist-client/components/chat-triggers.d.ts +0 -16
- package/dist-client/components/chat-triggers.js +0 -42
- package/dist-client/components/chat-triggers.js.map +0 -1
- package/dist-client/components/chat-triggers.test.d.ts +0 -1
- package/dist-client/components/chat-triggers.test.js +0 -61
- package/dist-client/components/chat-triggers.test.js.map +0 -1
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AiAgentResolver = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
/*
|
|
6
|
+
* The doors of a domain's AI agents (design/ai/agent-settings.md).
|
|
7
|
+
*
|
|
8
|
+
* The settings card reads and saves the agents of the domain it is in; the dock reads the agents a person may pick.
|
|
9
|
+
* Everything here is a thin door over ai-client-base, which owns the agents, their keys and their usage. A key never
|
|
10
|
+
* leaves the server: reads carry a hint of this domain's own key and nothing of a key from above.
|
|
11
|
+
*/
|
|
12
|
+
const type_graphql_1 = require("type-graphql");
|
|
13
|
+
require("@things-factory/auth-base");
|
|
14
|
+
const shell_1 = require("@things-factory/shell");
|
|
15
|
+
const ai_client_base_1 = require("@things-factory/ai-client-base");
|
|
16
|
+
let AiAgentDomain = class AiAgentDomain {
|
|
17
|
+
};
|
|
18
|
+
tslib_1.__decorate([
|
|
19
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.ID, { description: 'Domain id.' }),
|
|
20
|
+
tslib_1.__metadata("design:type", String)
|
|
21
|
+
], AiAgentDomain.prototype, "id", void 0);
|
|
22
|
+
tslib_1.__decorate([
|
|
23
|
+
(0, type_graphql_1.Field)({ description: 'Domain name.' }),
|
|
24
|
+
tslib_1.__metadata("design:type", String)
|
|
25
|
+
], AiAgentDomain.prototype, "name", void 0);
|
|
26
|
+
AiAgentDomain = tslib_1.__decorate([
|
|
27
|
+
(0, type_graphql_1.ObjectType)({ description: 'A domain, by id and name.' })
|
|
28
|
+
], AiAgentDomain);
|
|
29
|
+
let AiAgentView = class AiAgentView {
|
|
30
|
+
};
|
|
31
|
+
tslib_1.__decorate([
|
|
32
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.ID, { description: 'Agent id.' }),
|
|
33
|
+
tslib_1.__metadata("design:type", String)
|
|
34
|
+
], AiAgentView.prototype, "id", void 0);
|
|
35
|
+
tslib_1.__decorate([
|
|
36
|
+
(0, type_graphql_1.Field)({ description: 'The name a person picks it by.' }),
|
|
37
|
+
tslib_1.__metadata("design:type", String)
|
|
38
|
+
], AiAgentView.prototype, "name", void 0);
|
|
39
|
+
tslib_1.__decorate([
|
|
40
|
+
(0, type_graphql_1.Field)({ description: 'openai, anthropic or gemini.' }),
|
|
41
|
+
tslib_1.__metadata("design:type", String)
|
|
42
|
+
], AiAgentView.prototype, "provider", void 0);
|
|
43
|
+
tslib_1.__decorate([
|
|
44
|
+
(0, type_graphql_1.Field)({ description: 'The model it answers with.' }),
|
|
45
|
+
tslib_1.__metadata("design:type", String)
|
|
46
|
+
], AiAgentView.prototype, "model", void 0);
|
|
47
|
+
tslib_1.__decorate([
|
|
48
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'A gateway or proxy the provider is reached through.' }),
|
|
49
|
+
tslib_1.__metadata("design:type", String)
|
|
50
|
+
], AiAgentView.prototype, "baseURL", void 0);
|
|
51
|
+
tslib_1.__decorate([
|
|
52
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'OpenAI organization.' }),
|
|
53
|
+
tslib_1.__metadata("design:type", String)
|
|
54
|
+
], AiAgentView.prototype, "organization", void 0);
|
|
55
|
+
tslib_1.__decorate([
|
|
56
|
+
(0, type_graphql_1.Field)({ description: 'Off takes it out of this domain and every domain below.' }),
|
|
57
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
58
|
+
], AiAgentView.prototype, "active", void 0);
|
|
59
|
+
tslib_1.__decorate([
|
|
60
|
+
(0, type_graphql_1.Field)(() => AiAgentDomain, { description: 'The domain that declared it.' }),
|
|
61
|
+
tslib_1.__metadata("design:type", AiAgentDomain)
|
|
62
|
+
], AiAgentView.prototype, "owner", void 0);
|
|
63
|
+
tslib_1.__decorate([
|
|
64
|
+
(0, type_graphql_1.Field)({ description: 'Declared by a domain above. Read-only here.' }),
|
|
65
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
66
|
+
], AiAgentView.prototype, "inherited", void 0);
|
|
67
|
+
tslib_1.__decorate([
|
|
68
|
+
(0, type_graphql_1.Field)({ description: 'An inherited agent this domain does not use.' }),
|
|
69
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
70
|
+
], AiAgentView.prototype, "turnedOff", void 0);
|
|
71
|
+
tslib_1.__decorate([
|
|
72
|
+
(0, type_graphql_1.Field)({ description: 'own, inherited, overridden or missing - where the key that answers comes from.' }),
|
|
73
|
+
tslib_1.__metadata("design:type", String)
|
|
74
|
+
], AiAgentView.prototype, "keyState", void 0);
|
|
75
|
+
tslib_1.__decorate([
|
|
76
|
+
(0, type_graphql_1.Field)(() => AiAgentDomain, { nullable: true, description: 'The domain whose key answers.' }),
|
|
77
|
+
tslib_1.__metadata("design:type", AiAgentDomain)
|
|
78
|
+
], AiAgentView.prototype, "keyDomain", void 0);
|
|
79
|
+
tslib_1.__decorate([
|
|
80
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'A hint of this domain\'s own key, such as ••••abcd. Never given for a key from above.' }),
|
|
81
|
+
tslib_1.__metadata("design:type", String)
|
|
82
|
+
], AiAgentView.prototype, "keyHint", void 0);
|
|
83
|
+
tslib_1.__decorate([
|
|
84
|
+
(0, type_graphql_1.Field)({ description: 'Active, used here, and has a key - a person can pick it.' }),
|
|
85
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
86
|
+
], AiAgentView.prototype, "usable", void 0);
|
|
87
|
+
tslib_1.__decorate([
|
|
88
|
+
(0, type_graphql_1.Field)({ description: 'The agent a person gets before picking one.' }),
|
|
89
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
90
|
+
], AiAgentView.prototype, "isDefault", void 0);
|
|
91
|
+
tslib_1.__decorate([
|
|
92
|
+
(0, type_graphql_1.Field)(() => [AiAgentDomain], { description: 'For this domain\'s own agents: the domains below that use it.' }),
|
|
93
|
+
tslib_1.__metadata("design:type", Array)
|
|
94
|
+
], AiAgentView.prototype, "usedBelow", void 0);
|
|
95
|
+
AiAgentView = tslib_1.__decorate([
|
|
96
|
+
(0, type_graphql_1.ObjectType)({ description: 'One AI agent as the settings card shows it. The key itself is never here.' })
|
|
97
|
+
], AiAgentView);
|
|
98
|
+
let AiAgentSettings = class AiAgentSettings {
|
|
99
|
+
};
|
|
100
|
+
tslib_1.__decorate([
|
|
101
|
+
(0, type_graphql_1.Field)(() => [AiAgentDomain], { description: 'This domain and the domains above it, closest first.' }),
|
|
102
|
+
tslib_1.__metadata("design:type", Array)
|
|
103
|
+
], AiAgentSettings.prototype, "chain", void 0);
|
|
104
|
+
tslib_1.__decorate([
|
|
105
|
+
(0, type_graphql_1.Field)(() => [AiAgentView], { description: 'This domain\'s agents, then each domain above\'s, closest first.' }),
|
|
106
|
+
tslib_1.__metadata("design:type", Array)
|
|
107
|
+
], AiAgentSettings.prototype, "agents", void 0);
|
|
108
|
+
tslib_1.__decorate([
|
|
109
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The agent a person gets before picking one.' }),
|
|
110
|
+
tslib_1.__metadata("design:type", String)
|
|
111
|
+
], AiAgentSettings.prototype, "defaultAgentId", void 0);
|
|
112
|
+
tslib_1.__decorate([
|
|
113
|
+
(0, type_graphql_1.Field)({ description: 'own, inherited, first or none - how the default was decided.' }),
|
|
114
|
+
tslib_1.__metadata("design:type", String)
|
|
115
|
+
], AiAgentSettings.prototype, "defaultFrom", void 0);
|
|
116
|
+
tslib_1.__decorate([
|
|
117
|
+
(0, type_graphql_1.Field)({ description: 'configured or not-configured.' }),
|
|
118
|
+
tslib_1.__metadata("design:type", String)
|
|
119
|
+
], AiAgentSettings.prototype, "state", void 0);
|
|
120
|
+
tslib_1.__decorate([
|
|
121
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Why it is not configured: no-agent, no-agent-key or no-usable-agent.' }),
|
|
122
|
+
tslib_1.__metadata("design:type", String)
|
|
123
|
+
], AiAgentSettings.prototype, "reason", void 0);
|
|
124
|
+
AiAgentSettings = tslib_1.__decorate([
|
|
125
|
+
(0, type_graphql_1.ObjectType)({ description: 'A domain\'s AI agents and how its AI stands.' })
|
|
126
|
+
], AiAgentSettings);
|
|
127
|
+
let AiAgentChoice = class AiAgentChoice {
|
|
128
|
+
};
|
|
129
|
+
tslib_1.__decorate([
|
|
130
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.ID, { description: 'Agent id - what assistantChat takes as agentId.' }),
|
|
131
|
+
tslib_1.__metadata("design:type", String)
|
|
132
|
+
], AiAgentChoice.prototype, "id", void 0);
|
|
133
|
+
tslib_1.__decorate([
|
|
134
|
+
(0, type_graphql_1.Field)({ description: 'The name a person picks it by.' }),
|
|
135
|
+
tslib_1.__metadata("design:type", String)
|
|
136
|
+
], AiAgentChoice.prototype, "name", void 0);
|
|
137
|
+
tslib_1.__decorate([
|
|
138
|
+
(0, type_graphql_1.Field)({ description: 'openai, anthropic or gemini.' }),
|
|
139
|
+
tslib_1.__metadata("design:type", String)
|
|
140
|
+
], AiAgentChoice.prototype, "provider", void 0);
|
|
141
|
+
tslib_1.__decorate([
|
|
142
|
+
(0, type_graphql_1.Field)({ description: 'The model it answers with.' }),
|
|
143
|
+
tslib_1.__metadata("design:type", String)
|
|
144
|
+
], AiAgentChoice.prototype, "model", void 0);
|
|
145
|
+
tslib_1.__decorate([
|
|
146
|
+
(0, type_graphql_1.Field)({ description: 'The agent a person gets before picking one.' }),
|
|
147
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
148
|
+
], AiAgentChoice.prototype, "isDefault", void 0);
|
|
149
|
+
AiAgentChoice = tslib_1.__decorate([
|
|
150
|
+
(0, type_graphql_1.ObjectType)({ description: 'An AI agent a person may pick in the dock.' })
|
|
151
|
+
], AiAgentChoice);
|
|
152
|
+
let AiAgentInput = class AiAgentInput {
|
|
153
|
+
};
|
|
154
|
+
tslib_1.__decorate([
|
|
155
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.ID, { nullable: true, description: 'Empty for a new agent.' }),
|
|
156
|
+
tslib_1.__metadata("design:type", String)
|
|
157
|
+
], AiAgentInput.prototype, "id", void 0);
|
|
158
|
+
tslib_1.__decorate([
|
|
159
|
+
(0, type_graphql_1.Field)({ description: 'The name a person picks it by.' }),
|
|
160
|
+
tslib_1.__metadata("design:type", String)
|
|
161
|
+
], AiAgentInput.prototype, "name", void 0);
|
|
162
|
+
tslib_1.__decorate([
|
|
163
|
+
(0, type_graphql_1.Field)({ description: 'openai, anthropic or gemini.' }),
|
|
164
|
+
tslib_1.__metadata("design:type", String)
|
|
165
|
+
], AiAgentInput.prototype, "provider", void 0);
|
|
166
|
+
tslib_1.__decorate([
|
|
167
|
+
(0, type_graphql_1.Field)({ description: 'A model from aiProviderModels.' }),
|
|
168
|
+
tslib_1.__metadata("design:type", String)
|
|
169
|
+
], AiAgentInput.prototype, "model", void 0);
|
|
170
|
+
tslib_1.__decorate([
|
|
171
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'A gateway or proxy the provider is reached through.' }),
|
|
172
|
+
tslib_1.__metadata("design:type", String)
|
|
173
|
+
], AiAgentInput.prototype, "baseURL", void 0);
|
|
174
|
+
tslib_1.__decorate([
|
|
175
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'OpenAI organization.' }),
|
|
176
|
+
tslib_1.__metadata("design:type", String)
|
|
177
|
+
], AiAgentInput.prototype, "organization", void 0);
|
|
178
|
+
tslib_1.__decorate([
|
|
179
|
+
(0, type_graphql_1.Field)({ description: 'Off takes it out of this domain and every domain below.' }),
|
|
180
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
181
|
+
], AiAgentInput.prototype, "active", void 0);
|
|
182
|
+
tslib_1.__decorate([
|
|
183
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'A new API key. Left out, the stored key stays.' }),
|
|
184
|
+
tslib_1.__metadata("design:type", String)
|
|
185
|
+
], AiAgentInput.prototype, "apiKey", void 0);
|
|
186
|
+
AiAgentInput = tslib_1.__decorate([
|
|
187
|
+
(0, type_graphql_1.InputType)({ description: 'One of this domain\'s own agents as the settings card saves it.' })
|
|
188
|
+
], AiAgentInput);
|
|
189
|
+
let InheritedKeyInput = class InheritedKeyInput {
|
|
190
|
+
};
|
|
191
|
+
tslib_1.__decorate([
|
|
192
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.ID, { description: 'The inherited agent.' }),
|
|
193
|
+
tslib_1.__metadata("design:type", String)
|
|
194
|
+
], InheritedKeyInput.prototype, "agentId", void 0);
|
|
195
|
+
tslib_1.__decorate([
|
|
196
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'A key of this domain to answer the agent with.' }),
|
|
197
|
+
tslib_1.__metadata("design:type", String)
|
|
198
|
+
], InheritedKeyInput.prototype, "apiKey", void 0);
|
|
199
|
+
tslib_1.__decorate([
|
|
200
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Go back to the key of the domain above.' }),
|
|
201
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
202
|
+
], InheritedKeyInput.prototype, "clear", void 0);
|
|
203
|
+
InheritedKeyInput = tslib_1.__decorate([
|
|
204
|
+
(0, type_graphql_1.InputType)({ description: 'This domain\'s key for an agent it inherits.' })
|
|
205
|
+
], InheritedKeyInput);
|
|
206
|
+
let AiAgentsInput = class AiAgentsInput {
|
|
207
|
+
};
|
|
208
|
+
tslib_1.__decorate([
|
|
209
|
+
(0, type_graphql_1.Field)(() => [AiAgentInput], { description: 'The whole list of this domain\'s own agents. One left out is deleted.' }),
|
|
210
|
+
tslib_1.__metadata("design:type", Array)
|
|
211
|
+
], AiAgentsInput.prototype, "agents", void 0);
|
|
212
|
+
tslib_1.__decorate([
|
|
213
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'This domain\'s default - its own agent or an inherited one.' }),
|
|
214
|
+
tslib_1.__metadata("design:type", String)
|
|
215
|
+
], AiAgentsInput.prototype, "defaultAgentId", void 0);
|
|
216
|
+
tslib_1.__decorate([
|
|
217
|
+
(0, type_graphql_1.Field)(() => [String], { nullable: true, description: 'Inherited agents this domain does not use.' }),
|
|
218
|
+
tslib_1.__metadata("design:type", Array)
|
|
219
|
+
], AiAgentsInput.prototype, "turnedOff", void 0);
|
|
220
|
+
tslib_1.__decorate([
|
|
221
|
+
(0, type_graphql_1.Field)(() => [InheritedKeyInput], { nullable: true, description: 'This domain\'s keys for inherited agents.' }),
|
|
222
|
+
tslib_1.__metadata("design:type", Array)
|
|
223
|
+
], AiAgentsInput.prototype, "inheritedKeys", void 0);
|
|
224
|
+
AiAgentsInput = tslib_1.__decorate([
|
|
225
|
+
(0, type_graphql_1.InputType)({ description: 'A domain\'s agents as the settings card saves them.' })
|
|
226
|
+
], AiAgentsInput);
|
|
227
|
+
let AiUsageBucket = class AiUsageBucket {
|
|
228
|
+
};
|
|
229
|
+
tslib_1.__decorate([
|
|
230
|
+
(0, type_graphql_1.Field)({ description: 'The hour, day or month in the domain\'s time zone.' }),
|
|
231
|
+
tslib_1.__metadata("design:type", String)
|
|
232
|
+
], AiUsageBucket.prototype, "bucket", void 0);
|
|
233
|
+
tslib_1.__decorate([
|
|
234
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Agent id.' }),
|
|
235
|
+
tslib_1.__metadata("design:type", String)
|
|
236
|
+
], AiUsageBucket.prototype, "agentId", void 0);
|
|
237
|
+
tslib_1.__decorate([
|
|
238
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Agent name. Empty for a deleted agent.' }),
|
|
239
|
+
tslib_1.__metadata("design:type", String)
|
|
240
|
+
], AiUsageBucket.prototype, "agentName", void 0);
|
|
241
|
+
tslib_1.__decorate([
|
|
242
|
+
(0, type_graphql_1.Field)({ description: 'openai, anthropic or gemini.' }),
|
|
243
|
+
tslib_1.__metadata("design:type", String)
|
|
244
|
+
], AiUsageBucket.prototype, "provider", void 0);
|
|
245
|
+
tslib_1.__decorate([
|
|
246
|
+
(0, type_graphql_1.Field)({ description: 'The model the provider reported.' }),
|
|
247
|
+
tslib_1.__metadata("design:type", String)
|
|
248
|
+
], AiUsageBucket.prototype, "model", void 0);
|
|
249
|
+
tslib_1.__decorate([
|
|
250
|
+
(0, type_graphql_1.Field)({ description: 'The domain the calls were made in.' }),
|
|
251
|
+
tslib_1.__metadata("design:type", String)
|
|
252
|
+
], AiUsageBucket.prototype, "domainId", void 0);
|
|
253
|
+
tslib_1.__decorate([
|
|
254
|
+
(0, type_graphql_1.Field)({ description: 'Its name.' }),
|
|
255
|
+
tslib_1.__metadata("design:type", String)
|
|
256
|
+
], AiUsageBucket.prototype, "domainName", void 0);
|
|
257
|
+
tslib_1.__decorate([
|
|
258
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The person. Empty for a domain below and for calls with no person.' }),
|
|
259
|
+
tslib_1.__metadata("design:type", String)
|
|
260
|
+
], AiUsageBucket.prototype, "userId", void 0);
|
|
261
|
+
tslib_1.__decorate([
|
|
262
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The person\'s name.' }),
|
|
263
|
+
tslib_1.__metadata("design:type", String)
|
|
264
|
+
], AiUsageBucket.prototype, "userName", void 0);
|
|
265
|
+
tslib_1.__decorate([
|
|
266
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.Int, { description: 'Provider requests.' }),
|
|
267
|
+
tslib_1.__metadata("design:type", Number)
|
|
268
|
+
], AiUsageBucket.prototype, "calls", void 0);
|
|
269
|
+
tslib_1.__decorate([
|
|
270
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.Int, { description: 'Input tokens.' }),
|
|
271
|
+
tslib_1.__metadata("design:type", Number)
|
|
272
|
+
], AiUsageBucket.prototype, "inputTokens", void 0);
|
|
273
|
+
tslib_1.__decorate([
|
|
274
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.Int, { description: 'Output tokens.' }),
|
|
275
|
+
tslib_1.__metadata("design:type", Number)
|
|
276
|
+
], AiUsageBucket.prototype, "outputTokens", void 0);
|
|
277
|
+
tslib_1.__decorate([
|
|
278
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.Int, { description: 'Requests that failed.' }),
|
|
279
|
+
tslib_1.__metadata("design:type", Number)
|
|
280
|
+
], AiUsageBucket.prototype, "failures", void 0);
|
|
281
|
+
AiUsageBucket = tslib_1.__decorate([
|
|
282
|
+
(0, type_graphql_1.ObjectType)({ description: 'AI usage of one bucket, agent and person.' })
|
|
283
|
+
], AiUsageBucket);
|
|
284
|
+
let AiAgentResolver = class AiAgentResolver {
|
|
285
|
+
async aiAgentSettings(context) {
|
|
286
|
+
const { domain } = context.state;
|
|
287
|
+
const directory = await (0, ai_client_base_1.readAiAgentDirectory)(domain);
|
|
288
|
+
const nameOf = new Map(directory.chain.map(one => [one.id, one.name]));
|
|
289
|
+
const ownIds = directory.entries.filter(one => !one.inherited).map(one => one.spec.id);
|
|
290
|
+
const usedBelow = await (0, ai_client_base_1.readAgentUsersBelow)(domain, ownIds);
|
|
291
|
+
const capability = (0, ai_client_base_1.capabilityOf)(directory);
|
|
292
|
+
return {
|
|
293
|
+
chain: directory.chain,
|
|
294
|
+
agents: directory.entries.map(entry => agentView(entry, directory.defaultAgentId, nameOf, usedBelow.get(entry.spec.id) ?? [])),
|
|
295
|
+
defaultAgentId: directory.defaultAgentId,
|
|
296
|
+
defaultFrom: directory.defaultFrom,
|
|
297
|
+
state: capability.state,
|
|
298
|
+
reason: capability.reason
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
async aiAgentChoices(context) {
|
|
302
|
+
const directory = await (0, ai_client_base_1.readAiAgentDirectory)(context.state.domain);
|
|
303
|
+
return directory.entries
|
|
304
|
+
.filter(one => one.usable)
|
|
305
|
+
.map(one => ({
|
|
306
|
+
id: one.spec.id,
|
|
307
|
+
name: one.spec.name,
|
|
308
|
+
provider: one.spec.provider,
|
|
309
|
+
model: one.spec.model,
|
|
310
|
+
isDefault: one.spec.id === directory.defaultAgentId
|
|
311
|
+
}));
|
|
312
|
+
}
|
|
313
|
+
async aiProviderModels(provider, apiKey, agentId, baseURL, organization, context) {
|
|
314
|
+
let key = apiKey?.trim();
|
|
315
|
+
if (!key && agentId) {
|
|
316
|
+
const directory = await (0, ai_client_base_1.readAiAgentDirectory)(context.state.domain);
|
|
317
|
+
key = directory.entries.find(one => one.spec.id === agentId && !one.inherited)?.apiKey;
|
|
318
|
+
}
|
|
319
|
+
return (0, ai_client_base_1.listProviderModels)({ provider, apiKey: key ?? '', baseURL, organization });
|
|
320
|
+
}
|
|
321
|
+
async saveAiAgents(input, context) {
|
|
322
|
+
const { tx, domain, user } = context.state;
|
|
323
|
+
await (0, ai_client_base_1.saveAiAgents)(input, { tx, domain, user });
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
async aiUsageSummary(from, to, bucket, agentIds, userIds, includeDescendants, context) {
|
|
327
|
+
const size = bucket === 'hour' || bucket === 'month' ? bucket : 'day';
|
|
328
|
+
return (0, ai_client_base_1.summarizeAiUsage)(context.state.domain, { from, to, bucket: size, agentIds, userIds, includeDescendants: !!includeDescendants });
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
exports.AiAgentResolver = AiAgentResolver;
|
|
332
|
+
tslib_1.__decorate([
|
|
333
|
+
(0, type_graphql_1.Query)(() => AiAgentSettings, { description: 'This domain\'s AI agents, the ones it inherits, and how its AI stands.' }),
|
|
334
|
+
(0, type_graphql_1.Directive)('@privilege(category: "setting", privilege: "query", domainOwnerGranted: true)'),
|
|
335
|
+
tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
|
|
336
|
+
tslib_1.__metadata("design:type", Function),
|
|
337
|
+
tslib_1.__metadata("design:paramtypes", [Object]),
|
|
338
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
339
|
+
], AiAgentResolver.prototype, "aiAgentSettings", null);
|
|
340
|
+
tslib_1.__decorate([
|
|
341
|
+
(0, type_graphql_1.Query)(() => [AiAgentChoice], { description: 'The AI agents a person may pick in the dock - usable ones only.' }),
|
|
342
|
+
(0, type_graphql_1.Directive)('@privilege(category: "ai-assistant", privilege: "query", domainOwnerGranted: true)'),
|
|
343
|
+
tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
|
|
344
|
+
tslib_1.__metadata("design:type", Function),
|
|
345
|
+
tslib_1.__metadata("design:paramtypes", [Object]),
|
|
346
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
347
|
+
], AiAgentResolver.prototype, "aiAgentChoices", null);
|
|
348
|
+
tslib_1.__decorate([
|
|
349
|
+
(0, type_graphql_1.Query)(() => [String], {
|
|
350
|
+
description: 'The conversation models a provider offers to a key - a typed key, or the stored key of one of this domain\'s agents. A model is only ever picked from this list.'
|
|
351
|
+
}),
|
|
352
|
+
(0, type_graphql_1.Directive)('@privilege(category: "setting", privilege: "query", domainOwnerGranted: true)'),
|
|
353
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('provider')),
|
|
354
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('apiKey', { nullable: true })),
|
|
355
|
+
tslib_1.__param(2, (0, type_graphql_1.Arg)('agentId', { nullable: true })),
|
|
356
|
+
tslib_1.__param(3, (0, type_graphql_1.Arg)('baseURL', { nullable: true })),
|
|
357
|
+
tslib_1.__param(4, (0, type_graphql_1.Arg)('organization', { nullable: true })),
|
|
358
|
+
tslib_1.__param(5, (0, type_graphql_1.Ctx)()),
|
|
359
|
+
tslib_1.__metadata("design:type", Function),
|
|
360
|
+
tslib_1.__metadata("design:paramtypes", [String, String, String, String, String, Object]),
|
|
361
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
362
|
+
], AiAgentResolver.prototype, "aiProviderModels", null);
|
|
363
|
+
tslib_1.__decorate([
|
|
364
|
+
(0, type_graphql_1.Mutation)(() => Boolean, {
|
|
365
|
+
description: 'Saves this domain\'s AI agents and their keys in one transaction. Read aiAgentSettings again for how they now stand.'
|
|
366
|
+
}),
|
|
367
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
368
|
+
(0, type_graphql_1.Directive)('@privilege(category: "setting", privilege: "mutation", domainOwnerGranted: true)'),
|
|
369
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('input', () => AiAgentsInput)),
|
|
370
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
371
|
+
tslib_1.__metadata("design:type", Function),
|
|
372
|
+
tslib_1.__metadata("design:paramtypes", [AiAgentsInput, Object]),
|
|
373
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
374
|
+
], AiAgentResolver.prototype, "saveAiAgents", null);
|
|
375
|
+
tslib_1.__decorate([
|
|
376
|
+
(0, type_graphql_1.Query)(() => [AiUsageBucket], {
|
|
377
|
+
description: 'AI usage per bucket, agent and person, in this domain\'s time zone. With includeDescendants, what the domains below did with this domain\'s agents is added - per domain, without their people.'
|
|
378
|
+
}),
|
|
379
|
+
(0, type_graphql_1.Directive)('@privilege(category: "setting", privilege: "query", domainOwnerGranted: true)'),
|
|
380
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('from')),
|
|
381
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('to')),
|
|
382
|
+
tslib_1.__param(2, (0, type_graphql_1.Arg)('bucket', { defaultValue: 'day' })),
|
|
383
|
+
tslib_1.__param(3, (0, type_graphql_1.Arg)('agentIds', () => [String], { nullable: true })),
|
|
384
|
+
tslib_1.__param(4, (0, type_graphql_1.Arg)('userIds', () => [String], { nullable: true })),
|
|
385
|
+
tslib_1.__param(5, (0, type_graphql_1.Arg)('includeDescendants', { nullable: true })),
|
|
386
|
+
tslib_1.__param(6, (0, type_graphql_1.Ctx)()),
|
|
387
|
+
tslib_1.__metadata("design:type", Function),
|
|
388
|
+
tslib_1.__metadata("design:paramtypes", [Date,
|
|
389
|
+
Date, String, Array, Array, Boolean, Object]),
|
|
390
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
391
|
+
], AiAgentResolver.prototype, "aiUsageSummary", null);
|
|
392
|
+
exports.AiAgentResolver = AiAgentResolver = tslib_1.__decorate([
|
|
393
|
+
(0, type_graphql_1.Resolver)(),
|
|
394
|
+
(0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
|
|
395
|
+
], AiAgentResolver);
|
|
396
|
+
function agentView(entry, defaultAgentId, nameOf, usedBelow) {
|
|
397
|
+
const domainOf = (id) => (id ? { id, name: nameOf.get(id) ?? id } : undefined);
|
|
398
|
+
return {
|
|
399
|
+
id: entry.spec.id,
|
|
400
|
+
name: entry.spec.name,
|
|
401
|
+
provider: entry.spec.provider,
|
|
402
|
+
model: entry.spec.model,
|
|
403
|
+
baseURL: entry.spec.baseURL,
|
|
404
|
+
organization: entry.spec.organization,
|
|
405
|
+
active: entry.spec.active,
|
|
406
|
+
owner: domainOf(entry.ownerDomainId),
|
|
407
|
+
inherited: entry.inherited,
|
|
408
|
+
turnedOff: entry.turnedOff,
|
|
409
|
+
keyState: entry.keyState,
|
|
410
|
+
keyDomain: domainOf(entry.keyDomainId),
|
|
411
|
+
keyHint: entry.keyHint,
|
|
412
|
+
usable: entry.usable,
|
|
413
|
+
isDefault: entry.spec.id === defaultAgentId,
|
|
414
|
+
usedBelow: entry.inherited ? [] : usedBelow
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
//# sourceMappingURL=ai-agent-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-agent-resolver.js","sourceRoot":"","sources":["../../server/service/ai-agent-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The doors of a domain's AI agents (design/ai/agent-settings.md).\n *\n * The settings card reads and saves the agents of the domain it is in; the dock reads the agents a person may pick.\n * Everything here is a thin door over ai-client-base, which owns the agents, their keys and their usage. A key never\n * leaves the server: reads carry a hint of this domain's own key and nothing of a key from above.\n */\nimport { Arg, Ctx, Directive, Field, ID, InputType, Int, Mutation, ObjectType, Query, Resolver, UseMiddleware } from 'type-graphql'\nimport '@things-factory/auth-base'\nimport { SpeakRefusals } from '@things-factory/shell'\nimport {\n type AiAgentEntry,\n capabilityOf,\n listProviderModels,\n readAgentUsersBelow,\n readAiAgentDirectory,\n saveAiAgents,\n summarizeAiUsage\n} from '@things-factory/ai-client-base'\n\n@ObjectType({ description: 'A domain, by id and name.' })\nclass AiAgentDomain {\n @Field(() => ID, { description: 'Domain id.' })\n id: string\n\n @Field({ description: 'Domain name.' })\n name: string\n}\n\n@ObjectType({ description: 'One AI agent as the settings card shows it. The key itself is never here.' })\nclass AiAgentView {\n @Field(() => ID, { description: 'Agent id.' })\n id: string\n\n @Field({ description: 'The name a person picks it by.' })\n name: string\n\n @Field({ description: 'openai, anthropic or gemini.' })\n provider: string\n\n @Field({ description: 'The model it answers with.' })\n model: string\n\n @Field({ nullable: true, description: 'A gateway or proxy the provider is reached through.' })\n baseURL?: string\n\n @Field({ nullable: true, description: 'OpenAI organization.' })\n organization?: string\n\n @Field({ description: 'Off takes it out of this domain and every domain below.' })\n active: boolean\n\n @Field(() => AiAgentDomain, { description: 'The domain that declared it.' })\n owner: AiAgentDomain\n\n @Field({ description: 'Declared by a domain above. Read-only here.' })\n inherited: boolean\n\n @Field({ description: 'An inherited agent this domain does not use.' })\n turnedOff: boolean\n\n @Field({ description: 'own, inherited, overridden or missing - where the key that answers comes from.' })\n keyState: string\n\n @Field(() => AiAgentDomain, { nullable: true, description: 'The domain whose key answers.' })\n keyDomain?: AiAgentDomain\n\n @Field({ nullable: true, description: 'A hint of this domain\\'s own key, such as ••••abcd. Never given for a key from above.' })\n keyHint?: string\n\n @Field({ description: 'Active, used here, and has a key - a person can pick it.' })\n usable: boolean\n\n @Field({ description: 'The agent a person gets before picking one.' })\n isDefault: boolean\n\n @Field(() => [AiAgentDomain], { description: 'For this domain\\'s own agents: the domains below that use it.' })\n usedBelow: AiAgentDomain[]\n}\n\n@ObjectType({ description: 'A domain\\'s AI agents and how its AI stands.' })\nclass AiAgentSettings {\n @Field(() => [AiAgentDomain], { description: 'This domain and the domains above it, closest first.' })\n chain: AiAgentDomain[]\n\n @Field(() => [AiAgentView], { description: 'This domain\\'s agents, then each domain above\\'s, closest first.' })\n agents: AiAgentView[]\n\n @Field({ nullable: true, description: 'The agent a person gets before picking one.' })\n defaultAgentId?: string\n\n @Field({ description: 'own, inherited, first or none - how the default was decided.' })\n defaultFrom: string\n\n @Field({ description: 'configured or not-configured.' })\n state: string\n\n @Field({ nullable: true, description: 'Why it is not configured: no-agent, no-agent-key or no-usable-agent.' })\n reason?: string\n}\n\n@ObjectType({ description: 'An AI agent a person may pick in the dock.' })\nclass AiAgentChoice {\n @Field(() => ID, { description: 'Agent id - what assistantChat takes as agentId.' })\n id: string\n\n @Field({ description: 'The name a person picks it by.' })\n name: string\n\n @Field({ description: 'openai, anthropic or gemini.' })\n provider: string\n\n @Field({ description: 'The model it answers with.' })\n model: string\n\n @Field({ description: 'The agent a person gets before picking one.' })\n isDefault: boolean\n}\n\n@InputType({ description: 'One of this domain\\'s own agents as the settings card saves it.' })\nclass AiAgentInput {\n @Field(() => ID, { nullable: true, description: 'Empty for a new agent.' })\n id?: string\n\n @Field({ description: 'The name a person picks it by.' })\n name: string\n\n @Field({ description: 'openai, anthropic or gemini.' })\n provider: string\n\n @Field({ description: 'A model from aiProviderModels.' })\n model: string\n\n @Field({ nullable: true, description: 'A gateway or proxy the provider is reached through.' })\n baseURL?: string\n\n @Field({ nullable: true, description: 'OpenAI organization.' })\n organization?: string\n\n @Field({ description: 'Off takes it out of this domain and every domain below.' })\n active: boolean\n\n @Field({ nullable: true, description: 'A new API key. Left out, the stored key stays.' })\n apiKey?: string\n}\n\n@InputType({ description: 'This domain\\'s key for an agent it inherits.' })\nclass InheritedKeyInput {\n @Field(() => ID, { description: 'The inherited agent.' })\n agentId: string\n\n @Field({ nullable: true, description: 'A key of this domain to answer the agent with.' })\n apiKey?: string\n\n @Field({ nullable: true, description: 'Go back to the key of the domain above.' })\n clear?: boolean\n}\n\n@InputType({ description: 'A domain\\'s agents as the settings card saves them.' })\nclass AiAgentsInput {\n @Field(() => [AiAgentInput], { description: 'The whole list of this domain\\'s own agents. One left out is deleted.' })\n agents: AiAgentInput[]\n\n @Field({ nullable: true, description: 'This domain\\'s default - its own agent or an inherited one.' })\n defaultAgentId?: string\n\n @Field(() => [String], { nullable: true, description: 'Inherited agents this domain does not use.' })\n turnedOff?: string[]\n\n @Field(() => [InheritedKeyInput], { nullable: true, description: 'This domain\\'s keys for inherited agents.' })\n inheritedKeys?: InheritedKeyInput[]\n}\n\n@ObjectType({ description: 'AI usage of one bucket, agent and person.' })\nclass AiUsageBucket {\n @Field({ description: 'The hour, day or month in the domain\\'s time zone.' })\n bucket: string\n\n @Field({ nullable: true, description: 'Agent id.' })\n agentId?: string\n\n @Field({ nullable: true, description: 'Agent name. Empty for a deleted agent.' })\n agentName?: string\n\n @Field({ description: 'openai, anthropic or gemini.' })\n provider: string\n\n @Field({ description: 'The model the provider reported.' })\n model: string\n\n @Field({ description: 'The domain the calls were made in.' })\n domainId: string\n\n @Field({ description: 'Its name.' })\n domainName: string\n\n @Field({ nullable: true, description: 'The person. Empty for a domain below and for calls with no person.' })\n userId?: string\n\n @Field({ nullable: true, description: 'The person\\'s name.' })\n userName?: string\n\n @Field(() => Int, { description: 'Provider requests.' })\n calls: number\n\n @Field(() => Int, { description: 'Input tokens.' })\n inputTokens: number\n\n @Field(() => Int, { description: 'Output tokens.' })\n outputTokens: number\n\n @Field(() => Int, { description: 'Requests that failed.' })\n failures: number\n}\n\n@Resolver()\n@UseMiddleware(SpeakRefusals)\nexport class AiAgentResolver {\n @Query(() => AiAgentSettings, { description: 'This domain\\'s AI agents, the ones it inherits, and how its AI stands.' })\n @Directive('@privilege(category: \"setting\", privilege: \"query\", domainOwnerGranted: true)')\n async aiAgentSettings(@Ctx() context: ResolverContext): Promise<AiAgentSettings> {\n const { domain } = context.state\n const directory = await readAiAgentDirectory(domain)\n const nameOf = new Map(directory.chain.map(one => [one.id, one.name]))\n const ownIds = directory.entries.filter(one => !one.inherited).map(one => one.spec.id)\n const usedBelow = await readAgentUsersBelow(domain, ownIds)\n const capability = capabilityOf(directory)\n\n return {\n chain: directory.chain,\n agents: directory.entries.map(entry => agentView(entry, directory.defaultAgentId, nameOf, usedBelow.get(entry.spec.id) ?? [])),\n defaultAgentId: directory.defaultAgentId,\n defaultFrom: directory.defaultFrom,\n state: capability.state,\n reason: capability.reason\n }\n }\n\n @Query(() => [AiAgentChoice], { description: 'The AI agents a person may pick in the dock - usable ones only.' })\n @Directive('@privilege(category: \"ai-assistant\", privilege: \"query\", domainOwnerGranted: true)')\n async aiAgentChoices(@Ctx() context: ResolverContext): Promise<AiAgentChoice[]> {\n const directory = await readAiAgentDirectory(context.state.domain)\n return directory.entries\n .filter(one => one.usable)\n .map(one => ({\n id: one.spec.id,\n name: one.spec.name,\n provider: one.spec.provider,\n model: one.spec.model,\n isDefault: one.spec.id === directory.defaultAgentId\n }))\n }\n\n @Query(() => [String], {\n description:\n 'The conversation models a provider offers to a key - a typed key, or the stored key of one of this domain\\'s agents. A model is only ever picked from this list.'\n })\n @Directive('@privilege(category: \"setting\", privilege: \"query\", domainOwnerGranted: true)')\n async aiProviderModels(\n @Arg('provider') provider: string,\n @Arg('apiKey', { nullable: true }) apiKey: string,\n @Arg('agentId', { nullable: true }) agentId: string,\n @Arg('baseURL', { nullable: true }) baseURL: string,\n @Arg('organization', { nullable: true }) organization: string,\n @Ctx() context: ResolverContext\n ): Promise<string[]> {\n let key = apiKey?.trim()\n if (!key && agentId) {\n const directory = await readAiAgentDirectory(context.state.domain)\n key = directory.entries.find(one => one.spec.id === agentId && !one.inherited)?.apiKey\n }\n return listProviderModels({ provider, apiKey: key ?? '', baseURL, organization })\n }\n\n @Mutation(() => Boolean, {\n description: 'Saves this domain\\'s AI agents and their keys in one transaction. Read aiAgentSettings again for how they now stand.'\n })\n @Directive('@transaction')\n @Directive('@privilege(category: \"setting\", privilege: \"mutation\", domainOwnerGranted: true)')\n async saveAiAgents(@Arg('input', () => AiAgentsInput) input: AiAgentsInput, @Ctx() context: ResolverContext): Promise<boolean> {\n const { tx, domain, user } = context.state\n await saveAiAgents(input, { tx, domain, user })\n return true\n }\n\n @Query(() => [AiUsageBucket], {\n description:\n 'AI usage per bucket, agent and person, in this domain\\'s time zone. With includeDescendants, what the domains below did with this domain\\'s agents is added - per domain, without their people.'\n })\n @Directive('@privilege(category: \"setting\", privilege: \"query\", domainOwnerGranted: true)')\n async aiUsageSummary(\n @Arg('from') from: Date,\n @Arg('to') to: Date,\n @Arg('bucket', { defaultValue: 'day' }) bucket: string,\n @Arg('agentIds', () => [String], { nullable: true }) agentIds: string[],\n @Arg('userIds', () => [String], { nullable: true }) userIds: string[],\n @Arg('includeDescendants', { nullable: true }) includeDescendants: boolean,\n @Ctx() context: ResolverContext\n ): Promise<AiUsageBucket[]> {\n const size = bucket === 'hour' || bucket === 'month' ? bucket : 'day'\n return summarizeAiUsage(context.state.domain, { from, to, bucket: size, agentIds, userIds, includeDescendants: !!includeDescendants })\n }\n}\n\nfunction agentView(\n entry: AiAgentEntry,\n defaultAgentId: string | undefined,\n nameOf: Map<string, string>,\n usedBelow: { id: string; name: string }[]\n): AiAgentView {\n const domainOf = (id?: string) => (id ? { id, name: nameOf.get(id) ?? id } : undefined)\n return {\n id: entry.spec.id,\n name: entry.spec.name,\n provider: entry.spec.provider,\n model: entry.spec.model,\n baseURL: entry.spec.baseURL,\n organization: entry.spec.organization,\n active: entry.spec.active,\n owner: domainOf(entry.ownerDomainId)!,\n inherited: entry.inherited,\n turnedOff: entry.turnedOff,\n keyState: entry.keyState,\n keyDomain: domainOf(entry.keyDomainId),\n keyHint: entry.keyHint,\n usable: entry.usable,\n isDefault: entry.spec.id === defaultAgentId,\n usedBelow: entry.inherited ? [] : usedBelow\n }\n}\n"]}
|
|
@@ -12,6 +12,6 @@ declare class AiCapabilityView {
|
|
|
12
12
|
warnings: AiRegistrationWarning[];
|
|
13
13
|
}
|
|
14
14
|
export declare class AssistantCapabilityResolver {
|
|
15
|
-
aiCapability(
|
|
15
|
+
aiCapability(context: any): Promise<AiCapabilityView>;
|
|
16
16
|
}
|
|
17
17
|
export {};
|
|
@@ -42,15 +42,15 @@ tslib_1.__decorate([
|
|
|
42
42
|
tslib_1.__metadata("design:type", String)
|
|
43
43
|
], AiCapabilityView.prototype, "state", void 0);
|
|
44
44
|
tslib_1.__decorate([
|
|
45
|
-
(0, type_graphql_1.Field)({ nullable: true, description: '
|
|
45
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The provider of the domain\'s default AI agent.' }),
|
|
46
46
|
tslib_1.__metadata("design:type", String)
|
|
47
47
|
], AiCapabilityView.prototype, "provider", void 0);
|
|
48
48
|
tslib_1.__decorate([
|
|
49
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'The
|
|
49
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The model of the domain\'s default AI agent.' }),
|
|
50
50
|
tslib_1.__metadata("design:type", String)
|
|
51
51
|
], AiCapabilityView.prototype, "model", void 0);
|
|
52
52
|
tslib_1.__decorate([
|
|
53
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'Why it is not configured: no-
|
|
53
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Why it is not configured: no-agent · no-agent-key · no-usable-agent.' }),
|
|
54
54
|
tslib_1.__metadata("design:type", String)
|
|
55
55
|
], AiCapabilityView.prototype, "reason", void 0);
|
|
56
56
|
tslib_1.__decorate([
|
|
@@ -58,11 +58,11 @@ tslib_1.__decorate([
|
|
|
58
58
|
tslib_1.__metadata("design:type", Array)
|
|
59
59
|
], AiCapabilityView.prototype, "warnings", void 0);
|
|
60
60
|
AiCapabilityView = tslib_1.__decorate([
|
|
61
|
-
(0, type_graphql_1.ObjectType)({ description: "Whether this
|
|
61
|
+
(0, type_graphql_1.ObjectType)({ description: "Whether this domain has an AI, and what the registrations are missing." })
|
|
62
62
|
], AiCapabilityView);
|
|
63
63
|
let AssistantCapabilityResolver = class AssistantCapabilityResolver {
|
|
64
|
-
async aiCapability(
|
|
65
|
-
const capability = (0, ai_client_base_1.aiCapability)();
|
|
64
|
+
async aiCapability(context) {
|
|
65
|
+
const capability = await (0, ai_client_base_1.aiCapability)(context.state.domain);
|
|
66
66
|
const warnings = [...(0, ai_client_base_1.getToolRegistryWarnings)(), ...(0, index_js_1.getAssistantModeWarnings)()].map(warning => ({
|
|
67
67
|
code: warning.code,
|
|
68
68
|
params: warning.params,
|
|
@@ -74,7 +74,7 @@ let AssistantCapabilityResolver = class AssistantCapabilityResolver {
|
|
|
74
74
|
exports.AssistantCapabilityResolver = AssistantCapabilityResolver;
|
|
75
75
|
tslib_1.__decorate([
|
|
76
76
|
(0, type_graphql_1.Query)(() => AiCapabilityView, {
|
|
77
|
-
description: 'Whether this
|
|
77
|
+
description: 'Whether this domain has a usable AI agent, and which registrations are incomplete. Read this before offering to ask the assistant — do not find out by failing.'
|
|
78
78
|
}),
|
|
79
79
|
(0, type_graphql_1.Directive)('@privilege(category: "ai-assistant", privilege: "query", domainOwnerGranted: true)'),
|
|
80
80
|
tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-capability-resolver.js","sourceRoot":"","sources":["../../server/service/assistant-capability-resolver.ts"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;GAUG;AACH,+CAAiF;AACjF,qDAA6C;AAC7C,qCAAkC;AAElC,mEAAsF;AAEtF,wDAAoE;AAGpE,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;CAS1B,CAAA;AAPC;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,iEAAiE,EAAE,CAAC;;mDAC9E;AAGZ;IADC,IAAA,oBAAK,EAAC,GAAG,EAAE,CAAC,6BAAW,EAAE,EAAE,WAAW,EAAE,+DAA+D,EAAE,CAAC;;qDAChG;AAGX;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,6DAA6D,EAAE,CAAC;;sDACvE;AARX,qBAAqB;IAD1B,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,6EAA6E,EAAE,CAAC;GACrG,qBAAqB,CAS1B;AAGD,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;CAerB,CAAA;AAbC;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,qHAAqH,EAAE,CAAC;;+CACjI;AAGb;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"assistant-capability-resolver.js","sourceRoot":"","sources":["../../server/service/assistant-capability-resolver.ts"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;GAUG;AACH,+CAAiF;AACjF,qDAA6C;AAC7C,qCAAkC;AAElC,mEAAsF;AAEtF,wDAAoE;AAGpE,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;CAS1B,CAAA;AAPC;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,iEAAiE,EAAE,CAAC;;mDAC9E;AAGZ;IADC,IAAA,oBAAK,EAAC,GAAG,EAAE,CAAC,6BAAW,EAAE,EAAE,WAAW,EAAE,+DAA+D,EAAE,CAAC;;qDAChG;AAGX;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,6DAA6D,EAAE,CAAC;;sDACvE;AARX,qBAAqB;IAD1B,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,6EAA6E,EAAE,CAAC;GACrG,qBAAqB,CAS1B;AAGD,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;CAerB,CAAA;AAbC;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,qHAAqH,EAAE,CAAC;;+CACjI;AAGb;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;;kDACzE;AAGjB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;;+CACzE;AAGd;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sEAAsE,EAAE,CAAC;;gDAChG;AAGf;IADC,IAAA,oBAAK,EAAC,GAAG,EAAE,CAAC,CAAC,qBAAqB,CAAC,EAAE,EAAE,WAAW,EAAE,kFAAkF,EAAE,CAAC;;kDACzG;AAd7B,gBAAgB;IADrB,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,wEAAwE,EAAE,CAAC;GAChG,gBAAgB,CAerB;AAGM,IAAM,2BAA2B,GAAjC,MAAM,2BAA2B;IAKhC,AAAN,KAAK,CAAC,YAAY,CAAQ,OAAY;QACpC,MAAM,UAAU,GAAG,MAAM,IAAA,6BAAY,EAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAC3D,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAA,wCAAuB,GAAE,EAAE,GAAG,IAAA,mCAAwB,GAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC7F,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC,CAAA;QAEH,OAAO,EAAE,GAAG,UAAU,EAAE,QAAQ,EAAsB,CAAA;IACxD,CAAC;CACF,CAAA;AAfY,kEAA2B;AAKhC;IAJL,IAAA,oBAAK,EAAC,GAAG,EAAE,CAAC,gBAAgB,EAAE;QAC7B,WAAW,EAAE,iKAAiK;KAC/K,CAAC;IACD,IAAA,wBAAS,EAAC,oFAAoF,CAAC;IAC5E,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;+DASxB;sCAdU,2BAA2B;IADvC,IAAA,uBAAQ,GAAE;GACE,2BAA2B,CAevC","sourcesContent":["/*\n * One window for one question: what state is this deployment's AI in.\n *\n * Two things were being answered by failure or by a log line — whether a provider is configured at\n * all (standard A7-a), and which registrations are not yet what the contracts ask for (A1 stage one,\n * and the modes' `/` sentences). They are the same question asked by different people, so they come\n * back together, as codes.\n *\n * A screen reads this **before** offering to ask the assistant. It is a query: reading what a\n * deployment can do is reading.\n */\nimport { Ctx, Directive, Field, ObjectType, Query, Resolver } from 'type-graphql'\nimport { GraphQLJSON } from 'graphql-scalars'\nimport '@things-factory/auth-base'\n\nimport { aiCapability, getToolRegistryWarnings } from '@things-factory/ai-client-base'\n\nimport { getAssistantModeWarnings } from './assistant-mode/index.js'\n\n@ObjectType({ description: 'A registration that was accepted but is not yet what the contract asks for.' })\nclass AiRegistrationWarning {\n @Field({ description: 'What is missing, as a code — never prose a screen has to parse.' })\n code: string\n\n @Field(() => GraphQLJSON, { description: 'Which registration it is about (category, tool, mode, slash).' })\n params: any\n\n @Field({ description: 'The same thing in a sentence, for whoever reads a boot log.' })\n message: string\n}\n\n@ObjectType({ description: \"Whether this domain has an AI, and what the registrations are missing.\" })\nclass AiCapabilityView {\n @Field({ description: \"'configured' or 'not-configured'. A screen that has not asked yet knows a third state of its own: it does not know.\" })\n state: string\n\n @Field({ nullable: true, description: 'The provider of the domain\\'s default AI agent.' })\n provider?: string\n\n @Field({ nullable: true, description: 'The model of the domain\\'s default AI agent.' })\n model?: string\n\n @Field({ nullable: true, description: 'Why it is not configured: no-agent · no-agent-key · no-usable-agent.' })\n reason?: string\n\n @Field(() => [AiRegistrationWarning], { description: 'Tools with no declared privilege, and modes offering work their tools cannot do.' })\n warnings: AiRegistrationWarning[]\n}\n\n@Resolver()\nexport class AssistantCapabilityResolver {\n @Query(() => AiCapabilityView, {\n description: 'Whether this domain has a usable AI agent, and which registrations are incomplete. Read this before offering to ask the assistant — do not find out by failing.'\n })\n @Directive('@privilege(category: \"ai-assistant\", privilege: \"query\", domainOwnerGranted: true)')\n async aiCapability(@Ctx() context: any): Promise<AiCapabilityView> {\n const capability = await aiCapability(context.state.domain)\n const warnings = [...getToolRegistryWarnings(), ...getAssistantModeWarnings()].map(warning => ({\n code: warning.code,\n params: warning.params,\n message: warning.message\n }))\n\n return { ...capability, warnings } as AiCapabilityView\n }\n}\n"]}
|
|
@@ -14,10 +14,12 @@ declare class AssistantChatInput {
|
|
|
14
14
|
hostContext?: any;
|
|
15
15
|
truncateAfterMessageId?: string;
|
|
16
16
|
attachmentIds?: string[];
|
|
17
|
+
agentId?: string;
|
|
17
18
|
}
|
|
18
19
|
declare class AssistantChatOutput {
|
|
19
20
|
reply: string;
|
|
20
21
|
clientId: string;
|
|
22
|
+
agentId?: string;
|
|
21
23
|
sessionId?: string;
|
|
22
24
|
userMessageId?: string;
|
|
23
25
|
assistantMessageId?: string;
|