@framers/agentos 0.15.64 → 0.15.65
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/.github/badges/tests.json +1 -1
- package/README.md +2 -2
- package/dist/agents/agency/AgencyRegistry.d.ts +10 -0
- package/dist/agents/agency/AgencyRegistry.d.ts.map +1 -1
- package/dist/agents/agency/AgencyRegistry.js +38 -0
- package/dist/agents/agency/AgencyRegistry.js.map +1 -1
- package/dist/api/AgentOS.d.ts +21 -0
- package/dist/api/AgentOS.d.ts.map +1 -1
- package/dist/api/AgentOS.js +43 -0
- package/dist/api/AgentOS.js.map +1 -1
- package/dist/api/agent.d.ts +8 -5
- package/dist/api/agent.d.ts.map +1 -1
- package/dist/api/agent.js.map +1 -1
- package/dist/api/gmi.d.ts.map +1 -1
- package/dist/api/gmi.js +27 -14
- package/dist/api/gmi.js.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/runtime/WorkflowFacade.d.ts +6 -0
- package/dist/api/runtime/WorkflowFacade.d.ts.map +1 -1
- package/dist/api/runtime/WorkflowFacade.js +7 -0
- package/dist/api/runtime/WorkflowFacade.js.map +1 -1
- package/dist/api/runtime/agencyLaunch/gmiLaunchTool.d.ts +3 -2
- package/dist/api/runtime/agencyLaunch/gmiLaunchTool.d.ts.map +1 -1
- package/dist/api/runtime/agencyLaunch/gmiLaunchTool.js +122 -61
- package/dist/api/runtime/agencyLaunch/gmiLaunchTool.js.map +1 -1
- package/dist/api/runtime/agencyLaunch/index.d.ts +11 -0
- package/dist/api/runtime/agencyLaunch/index.d.ts.map +1 -0
- package/dist/api/runtime/agencyLaunch/index.js +11 -0
- package/dist/api/runtime/agencyLaunch/index.js.map +1 -0
- package/dist/api/runtime/agencyLaunch/launchRegistry.d.ts +4 -1
- package/dist/api/runtime/agencyLaunch/launchRegistry.d.ts.map +1 -1
- package/dist/api/runtime/agencyLaunch/launchRegistry.js.map +1 -1
- package/dist/api/runtime/agencyLaunch/meteredProviderManager.d.ts +13 -0
- package/dist/api/runtime/agencyLaunch/meteredProviderManager.d.ts.map +1 -1
- package/dist/api/runtime/agencyLaunch/meteredProviderManager.js +19 -0
- package/dist/api/runtime/agencyLaunch/meteredProviderManager.js.map +1 -1
- package/dist/api/runtime/agencyLaunch/runLaunch.d.ts +32 -3
- package/dist/api/runtime/agencyLaunch/runLaunch.d.ts.map +1 -1
- package/dist/api/runtime/agencyLaunch/runLaunch.js +57 -9
- package/dist/api/runtime/agencyLaunch/runLaunch.js.map +1 -1
- package/dist/api/runtime/agencyLaunch/runtimeLaunchTool.d.ts +84 -0
- package/dist/api/runtime/agencyLaunch/runtimeLaunchTool.d.ts.map +1 -0
- package/dist/api/runtime/agencyLaunch/runtimeLaunchTool.js +344 -0
- package/dist/api/runtime/agencyLaunch/runtimeLaunchTool.js.map +1 -0
- package/dist/api/runtime/agencyLaunch/runtimeSeat.d.ts +61 -0
- package/dist/api/runtime/agencyLaunch/runtimeSeat.d.ts.map +1 -0
- package/dist/api/runtime/agencyLaunch/runtimeSeat.js +277 -0
- package/dist/api/runtime/agencyLaunch/runtimeSeat.js.map +1 -0
- package/dist/api/runtime/agencyLaunch/seatToolView.d.ts +11 -0
- package/dist/api/runtime/agencyLaunch/seatToolView.d.ts.map +1 -0
- package/dist/api/runtime/agencyLaunch/seatToolView.js +69 -0
- package/dist/api/runtime/agencyLaunch/seatToolView.js.map +1 -0
- package/dist/api/runtime/agencyLaunch/types.d.ts +126 -13
- package/dist/api/runtime/agencyLaunch/types.d.ts.map +1 -1
- package/dist/api/runtime/agencyLaunch/types.js +102 -2
- package/dist/api/runtime/agencyLaunch/types.js.map +1 -1
- package/dist/api/runtime/capabilityContract.d.ts +7 -1
- package/dist/api/runtime/capabilityContract.d.ts.map +1 -1
- package/dist/api/runtime/capabilityContract.js +6 -0
- package/dist/api/runtime/capabilityContract.js.map +1 -1
- package/dist/api/runtime/gmiPersona.d.ts +6 -0
- package/dist/api/runtime/gmiPersona.d.ts.map +1 -1
- package/dist/api/runtime/gmiPersona.js +9 -1
- package/dist/api/runtime/gmiPersona.js.map +1 -1
- package/dist/api/runtime/gmiSession.d.ts +4 -3
- package/dist/api/runtime/gmiSession.d.ts.map +1 -1
- package/dist/api/runtime/gmiSession.js +1 -1
- package/dist/api/runtime/gmiSession.js.map +1 -1
- package/dist/api/runtime/lightweightAgentDiagnostics.d.ts +14 -6
- package/dist/api/runtime/lightweightAgentDiagnostics.d.ts.map +1 -1
- package/dist/api/runtime/lightweightAgentDiagnostics.js +10 -4
- package/dist/api/runtime/lightweightAgentDiagnostics.js.map +1 -1
- package/dist/api/types.d.ts +11 -5
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/types.js.map +1 -1
- package/dist/cognition/emergent/CreateWorkflowTool.d.ts +12 -2
- package/dist/cognition/emergent/CreateWorkflowTool.d.ts.map +1 -1
- package/dist/cognition/emergent/CreateWorkflowTool.js +12 -2
- package/dist/cognition/emergent/CreateWorkflowTool.js.map +1 -1
- package/dist/cognition/emergent/EmergentCapabilityEngine.d.ts +8 -1
- package/dist/cognition/emergent/EmergentCapabilityEngine.d.ts.map +1 -1
- package/dist/cognition/emergent/EmergentCapabilityEngine.js +11 -0
- package/dist/cognition/emergent/EmergentCapabilityEngine.js.map +1 -1
- package/dist/cognition/emergent/SelfImprovementConfig.d.ts +8 -2
- package/dist/cognition/emergent/SelfImprovementConfig.d.ts.map +1 -1
- package/dist/cognition/emergent/SelfImprovementConfig.js.map +1 -1
- package/dist/cognition/emergent/StepGate.d.ts +15 -3
- package/dist/cognition/emergent/StepGate.d.ts.map +1 -1
- package/dist/cognition/emergent/StepGate.js +33 -5
- package/dist/cognition/emergent/StepGate.js.map +1 -1
- package/dist/cognition/emergent/types.d.ts +4 -2
- package/dist/cognition/emergent/types.d.ts.map +1 -1
- package/dist/cognition/emergent/types.js.map +1 -1
- package/dist/cognition/substrate/GMI.d.ts +8 -2
- package/dist/cognition/substrate/GMI.d.ts.map +1 -1
- package/dist/cognition/substrate/GMI.js +52 -5
- package/dist/cognition/substrate/GMI.js.map +1 -1
- package/dist/cognition/substrate/GMIManager.d.ts +88 -9
- package/dist/cognition/substrate/GMIManager.d.ts.map +1 -1
- package/dist/cognition/substrate/GMIManager.js +202 -11
- package/dist/cognition/substrate/GMIManager.js.map +1 -1
- package/dist/cognition/substrate/IGMI.d.ts +7 -0
- package/dist/cognition/substrate/IGMI.d.ts.map +1 -1
- package/dist/cognition/substrate/IGMI.js.map +1 -1
- package/dist/core/llm/providers/AIModelProviderManager.d.ts +11 -0
- package/dist/core/llm/providers/AIModelProviderManager.d.ts.map +1 -1
- package/dist/core/llm/providers/AIModelProviderManager.js +18 -0
- package/dist/core/llm/providers/AIModelProviderManager.js.map +1 -1
- package/dist/core/tools/ITool.d.ts +11 -5
- package/dist/core/tools/ITool.d.ts.map +1 -1
- package/dist/core/tools/ToolExecutor.d.ts +15 -9
- package/dist/core/tools/ToolExecutor.d.ts.map +1 -1
- package/dist/core/tools/ToolExecutor.js.map +1 -1
- package/dist/core/tools/ToolOrchestrator.d.ts +8 -0
- package/dist/core/tools/ToolOrchestrator.d.ts.map +1 -1
- package/dist/core/tools/ToolOrchestrator.js +37 -11
- package/dist/core/tools/ToolOrchestrator.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -12,7 +12,7 @@ import { InMemoryWorkingMemory } from './memory/InMemoryWorkingMemory.js';
|
|
|
12
12
|
import { ConversationManager } from '../../core/conversation/ConversationManager.js';
|
|
13
13
|
import { ConversationContext } from '../../core/conversation/ConversationContext.js';
|
|
14
14
|
import { GMIError, GMIErrorCode } from '../../core/utils/errors.js';
|
|
15
|
-
import { IPromptEngine } from '../../core/llm/IPromptEngine.js';
|
|
15
|
+
import type { IPromptEngine, PromptEngineConfig } from '../../core/llm/IPromptEngine.js';
|
|
16
16
|
import { AIModelProviderManager } from '../../core/llm/providers/AIModelProviderManager.js';
|
|
17
17
|
import { IUtilityAI } from '../nlp/ai_utilities/IUtilityAI.js';
|
|
18
18
|
import { IToolOrchestrator } from '../../core/tools/IToolOrchestrator.js';
|
|
@@ -55,6 +55,12 @@ export interface GMIManagerConfig {
|
|
|
55
55
|
* section on every turn. Without it the manager builds GMIs as it did before the layer existed.
|
|
56
56
|
*/
|
|
57
57
|
learningLayer?: ILearningLayer;
|
|
58
|
+
/**
|
|
59
|
+
* The prompt-engine config of the GMIs `createAgencySeat` builds for the teams a GMI launches (`launch_agency` on the
|
|
60
|
+
* full runtime). Their engine gets no utility AI, so it truncates history and makes no model call. AgentOS sets it
|
|
61
|
+
* from its own `promptEngineConfig` when `agencies` is set.
|
|
62
|
+
*/
|
|
63
|
+
agencySeatPromptEngineConfig?: PromptEngineConfig;
|
|
58
64
|
}
|
|
59
65
|
export interface GMICognitiveMemoryFactoryInput {
|
|
60
66
|
gmiInstanceId: string;
|
|
@@ -78,6 +84,31 @@ export interface GMIAgencyContextOptions {
|
|
|
78
84
|
evolutionRules?: PersonaEvolutionRule[];
|
|
79
85
|
evolutionContext?: PersonaEvolutionContext;
|
|
80
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* One seat of a team a GMI launched on the full runtime (`launch_agency`): what {@link GMIManager.createAgencySeat}
|
|
89
|
+
* builds. The launch passes the views the seat runs through, so the manager imports nothing of the launch.
|
|
90
|
+
*/
|
|
91
|
+
export interface AgencySeatSpec {
|
|
92
|
+
/**
|
|
93
|
+
* `seat:<agencyId>:<role>`; refused when a GMI already serves it. Until the seat is released no request acquires
|
|
94
|
+
* a GMI in it and no feedback reaches its GMI.
|
|
95
|
+
*/
|
|
96
|
+
seatSessionId: string;
|
|
97
|
+
/** The parent turn's user: the seat's tools and the tier check see it. */
|
|
98
|
+
userId: string;
|
|
99
|
+
/** A registered persona, by id (a persistent member), or the definition a launch made for a temporary seat. */
|
|
100
|
+
persona: {
|
|
101
|
+
personaId: string;
|
|
102
|
+
} | {
|
|
103
|
+
definition: IPersonaDefinition;
|
|
104
|
+
};
|
|
105
|
+
/** The seat's tool orchestrator: a view the launch makes over the shared one. */
|
|
106
|
+
toolView: (base: IToolOrchestrator) => IToolOrchestrator;
|
|
107
|
+
/** The seat's provider manager: a view the launch makes over the runtime's; the runtime's own when absent. */
|
|
108
|
+
providerManager?: (base: AIModelProviderManager) => AIModelProviderManager;
|
|
109
|
+
/** The seat's step limit; the GMI's default when absent. */
|
|
110
|
+
maxToolLoopIterations?: number;
|
|
111
|
+
}
|
|
81
112
|
/**
|
|
82
113
|
* Manages the lifecycle of Generalized Mind Instances (GMIs).
|
|
83
114
|
*/
|
|
@@ -101,8 +132,8 @@ export declare class GMIManager {
|
|
|
101
132
|
private isInitialized;
|
|
102
133
|
readonly managerId: string;
|
|
103
134
|
/**
|
|
104
|
-
* One promise per getOrCreateGMIForSession() call in
|
|
105
|
-
* the call returns or throws. shutdown() waits for them.
|
|
135
|
+
* One promise per getOrCreateGMIForSession() or createAgencySeat() call in
|
|
136
|
+
* flight, resolved when the call returns or throws. shutdown() waits for them.
|
|
106
137
|
*/
|
|
107
138
|
private readonly creationsInFlight;
|
|
108
139
|
/**
|
|
@@ -111,6 +142,14 @@ export declare class GMIManager {
|
|
|
111
142
|
* waits for it and never hands out a GMI that is shutting down.
|
|
112
143
|
*/
|
|
113
144
|
private readonly deactivations;
|
|
145
|
+
/**
|
|
146
|
+
* The session of each seat createAgencySeat() registered, mapped to the seat's GMI instance id, until the seat is
|
|
147
|
+
* released. A seat's GMI serves its team alone: an acquisition that names one is refused and feedback that names one
|
|
148
|
+
* is not recorded, so a request can neither run a turn on a seat's GMI (its tools, budget and working memory are the
|
|
149
|
+
* team's) nor shut a running seat down by asking for another persona; the idle cleanup passes it by, since its launch
|
|
150
|
+
* releases it.
|
|
151
|
+
*/
|
|
152
|
+
private readonly agencySeatSessions;
|
|
114
153
|
constructor(config: GMIManagerConfig, subscriptionService: ISubscriptionService | undefined, authService: IAuthService | undefined, conversationManager: ConversationManager, promptEngine: IPromptEngine, llmProviderManager: AIModelProviderManager, utilityAI: IUtilityAI, toolOrchestrator: IToolOrchestrator, retrievalAugmentor?: IRetrievalAugmentor, personaLoader?: IPersonaLoader);
|
|
115
154
|
private validateGMIDependencies;
|
|
116
155
|
private getAgencySeatKey;
|
|
@@ -146,7 +185,8 @@ export declare class GMIManager {
|
|
|
146
185
|
private assembleLearning;
|
|
147
186
|
private assembleGMIBaseConfig;
|
|
148
187
|
/**
|
|
149
|
-
* The GMI of a session: the one the session has, or a new one built for it.
|
|
188
|
+
* The GMI of a session: the one the session has, or a new one built for it. A session that a seat of a team a GMI
|
|
189
|
+
* launched holds (createAgencySeat()) is refused with `PERMISSION_DENIED` until the seat is released.
|
|
150
190
|
*
|
|
151
191
|
* @param turnOrganizationId - The resolved organization of the turn the GMI is acquired for (`''` for none).
|
|
152
192
|
* With a learning layer a new GMI's learner session is bound under it; a caller that cannot resolve it before
|
|
@@ -165,6 +205,43 @@ export declare class GMIManager {
|
|
|
165
205
|
private resolveGMIForSession;
|
|
166
206
|
getGMIByInstanceId(gmiInstanceId: string): IGMI | undefined;
|
|
167
207
|
deactivateGMIForSession(sessionId: string): Promise<boolean>;
|
|
208
|
+
/** The seat GMIs' prompt engine: built once, with no utility AI; a build that fails is not kept. */
|
|
209
|
+
private agencySeatEngine?;
|
|
210
|
+
private agencySeatPromptEngine;
|
|
211
|
+
/** A seat's persona: the definition a launch made, or a registered one the user may use. */
|
|
212
|
+
private agencySeatPersona;
|
|
213
|
+
/**
|
|
214
|
+
* Builds and registers the GMI of one seat of a team a GMI launched (`launch_agency` on the full runtime): the
|
|
215
|
+
* registered persona a `personaId` seat names, checked as a session's persona is (strict validation, the user's
|
|
216
|
+
* tier), or the definition the launch made for a temporary seat. The GMI has no cognitive memory and no retrieval
|
|
217
|
+
* augmentor (its input is a manager's or a sibling's text), a prompt engine and a statistical utility that
|
|
218
|
+
* make no model call, the tool view and provider manager the launch gives it, and, with the runtime's learning layer,
|
|
219
|
+
* no learner (a workflow seat's source): it still renders its persona's traits, and with the layer off it sends no
|
|
220
|
+
* personality section. It is registered under the seat session id, so its own tool calls resolve it; `release()`
|
|
221
|
+
* shuts it down and takes it out of the manager, and a handle released after the manager shut down leaves alone
|
|
222
|
+
* whatever holds the session since. Until then the session is the seat's:
|
|
223
|
+
* `getOrCreateGMIForSession()` refuses it with `PERMISSION_DENIED`, whatever persona the request names (a request
|
|
224
|
+
* whose GMI was being built when the seat took the session included, that GMI shut down unregistered),
|
|
225
|
+
* `processUserFeedback()` records nothing for it and `cleanupInactiveGMIs()` passes it by. `shutdown()` waits for a
|
|
226
|
+
* seat being built, as it waits for a session's GMI, and the build then fails with its GMI shut down.
|
|
227
|
+
*
|
|
228
|
+
* @throws {GMIManagerError} `PERSONA_NOT_FOUND` for an unknown persona; `PERMISSION_DENIED` for one the user's tier or
|
|
229
|
+
* strict validation refuses; `INVALID_STATE` for a session that already has a GMI; `CONFIGURATION_ERROR` without
|
|
230
|
+
* `agencySeatPromptEngineConfig`; `NOT_INITIALIZED` when the manager is not, or shuts down while the seat is built.
|
|
231
|
+
* @throws {GMIError} `GMI_INITIALIZATION_ERROR` when the GMI does not initialize.
|
|
232
|
+
*/
|
|
233
|
+
createAgencySeat(spec: AgencySeatSpec): Promise<{
|
|
234
|
+
gmi: IGMI;
|
|
235
|
+
personaId: string;
|
|
236
|
+
release(): Promise<void>;
|
|
237
|
+
}>;
|
|
238
|
+
/** The work of {@link GMIManager.createAgencySeat}. */
|
|
239
|
+
private buildAgencySeat;
|
|
240
|
+
/**
|
|
241
|
+
* Releases one seat's GMI and then its hold on the session. Only the seat's own GMI and hold go: once the manager has
|
|
242
|
+
* shut down, the session may hold a GMI or a seat that came after it, which stays.
|
|
243
|
+
*/
|
|
244
|
+
private releaseAgencySeat;
|
|
168
245
|
/**
|
|
169
246
|
* Shuts down the GMI bound to a session and removes it from both maps. It
|
|
170
247
|
* skips the initialization check because `shutdown()` marks the manager
|
|
@@ -190,16 +267,18 @@ export declare class GMIManager {
|
|
|
190
267
|
*/
|
|
191
268
|
private shutDownGMI;
|
|
192
269
|
/**
|
|
193
|
-
* Waits, at most `shutdownTimeoutMs`, for the getOrCreateGMIForSession()
|
|
194
|
-
* calls in flight to settle. A call still running after
|
|
195
|
-
* GMI it builds once it gets that far.
|
|
270
|
+
* Waits, at most `shutdownTimeoutMs`, for the getOrCreateGMIForSession() and
|
|
271
|
+
* createAgencySeat() calls in flight to settle. A call still running after
|
|
272
|
+
* that shuts down the GMI it builds once it gets that far.
|
|
196
273
|
*/
|
|
197
274
|
private creationsSettled;
|
|
198
275
|
cleanupInactiveGMIs(inactivityThresholdMinutes?: number): Promise<number>;
|
|
199
276
|
shutdown(): Promise<void>;
|
|
200
277
|
/**
|
|
201
|
-
* Routes user feedback to the GMI that serves the session
|
|
202
|
-
*
|
|
278
|
+
* Routes user feedback to the GMI that serves the session; feedback that
|
|
279
|
+
* names the session of a seat of a launched team (createAgencySeat()) is not
|
|
280
|
+
* recorded. The payload is normalized first (see
|
|
281
|
+
* {@link normalizeUserFeedback}): a `rating` label
|
|
203
282
|
* decides the polarity, otherwise a numeric rating is read on the 1 to 5
|
|
204
283
|
* scale. The GMI then records a trace entry and, when cognitive memory is
|
|
205
284
|
* configured, stores the feedback and any correction as memories of the user.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GMIManager.d.ts","sourceRoot":"","sources":["../../../src/cognition/substrate/GMIManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,IAAI,EAAE,aAAa,EAAsB,MAAM,QAAQ,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAIL,6BAA6B,EAG9B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhF,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAqB,MAAM,uBAAuB,CAAC;AACnG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAA2B,MAAM,4BAA4B,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"GMIManager.d.ts","sourceRoot":"","sources":["../../../src/cognition/substrate/GMIManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,11 +10,14 @@ import { validatePersonas, formatAggregateReport, applyStrictMode } from './pers
|
|
|
10
10
|
import { PersonaLoader } from './personas/PersonaLoader.js';
|
|
11
11
|
import { InMemoryWorkingMemory } from './memory/InMemoryWorkingMemory.js';
|
|
12
12
|
import { GMIError, GMIErrorCode, createGMIErrorFromError } from '../../core/utils/errors.js';
|
|
13
|
+
import { PromptEngine } from '../../core/llm/PromptEngine.js';
|
|
14
|
+
import { StatisticalUtilityAI } from '../nlp/ai_utilities/StatisticalUtilityAI.js';
|
|
13
15
|
import { PersonaOverlayManager } from './persona_overlays/PersonaOverlayManager.js';
|
|
14
16
|
import { resolveSecretForProvider } from '../../core/config/extensionSecrets.js';
|
|
15
17
|
import { feedbackTraceMessage, normalizeUserFeedback } from './userFeedback.js';
|
|
16
18
|
import { settlesWithin, shutdownTimeoutOrDefault } from './shutdownBound.js';
|
|
17
19
|
import { normalizeHexacoTraits } from './personas/hexaco.js';
|
|
20
|
+
import { normalizePersonaDefinition } from './personas/personaNormalization.js';
|
|
18
21
|
import { traitOverlayPatch } from './personas/personalityPrompt.js';
|
|
19
22
|
import { deferLearnerSession } from '../learning/LearnerSession.js';
|
|
20
23
|
/**
|
|
@@ -70,8 +73,8 @@ export class GMIManager {
|
|
|
70
73
|
constructor(config, subscriptionService, authService, conversationManager, promptEngine, llmProviderManager, utilityAI, toolOrchestrator, retrievalAugmentor, personaLoader) {
|
|
71
74
|
this.isInitialized = false;
|
|
72
75
|
/**
|
|
73
|
-
* One promise per getOrCreateGMIForSession() call in
|
|
74
|
-
* the call returns or throws. shutdown() waits for them.
|
|
76
|
+
* One promise per getOrCreateGMIForSession() or createAgencySeat() call in
|
|
77
|
+
* flight, resolved when the call returns or throws. shutdown() waits for them.
|
|
75
78
|
*/
|
|
76
79
|
this.creationsInFlight = new Set();
|
|
77
80
|
/**
|
|
@@ -80,6 +83,14 @@ export class GMIManager {
|
|
|
80
83
|
* waits for it and never hands out a GMI that is shutting down.
|
|
81
84
|
*/
|
|
82
85
|
this.deactivations = new Map();
|
|
86
|
+
/**
|
|
87
|
+
* The session of each seat createAgencySeat() registered, mapped to the seat's GMI instance id, until the seat is
|
|
88
|
+
* released. A seat's GMI serves its team alone: an acquisition that names one is refused and feedback that names one
|
|
89
|
+
* is not recorded, so a request can neither run a turn on a seat's GMI (its tools, budget and working memory are the
|
|
90
|
+
* team's) nor shut a running seat down by asking for another persona; the idle cleanup passes it by, since its launch
|
|
91
|
+
* releases it.
|
|
92
|
+
*/
|
|
93
|
+
this.agencySeatSessions = new Map();
|
|
83
94
|
this.managerId = `gmi-manager-${uuidv4()}`;
|
|
84
95
|
if (!config || !config.personaLoaderConfig) {
|
|
85
96
|
throw new GMIManagerError('Invalid GMIManager configuration: personaLoaderConfig is required.', GMIErrorCode.CONFIGURATION_ERROR, { providedConfig: config });
|
|
@@ -93,6 +104,7 @@ export class GMIManager {
|
|
|
93
104
|
cognitiveMemoryFactory: config.cognitiveMemoryFactory,
|
|
94
105
|
shutdownTimeoutMs: shutdownTimeoutOrDefault(config.shutdownTimeoutMs),
|
|
95
106
|
learningLayer: config.learningLayer,
|
|
107
|
+
agencySeatPromptEngineConfig: config.agencySeatPromptEngineConfig,
|
|
96
108
|
};
|
|
97
109
|
this.subscriptionService = subscriptionService;
|
|
98
110
|
this.authService = authService;
|
|
@@ -495,7 +507,8 @@ export class GMIManager {
|
|
|
495
507
|
};
|
|
496
508
|
}
|
|
497
509
|
/**
|
|
498
|
-
* The GMI of a session: the one the session has, or a new one built for it.
|
|
510
|
+
* The GMI of a session: the one the session has, or a new one built for it. A session that a seat of a team a GMI
|
|
511
|
+
* launched holds (createAgencySeat()) is refused with `PERMISSION_DENIED` until the seat is released.
|
|
499
512
|
*
|
|
500
513
|
* @param turnOrganizationId - The resolved organization of the turn the GMI is acquired for (`''` for none).
|
|
501
514
|
* With a learning layer a new GMI's learner session is bound under it; a caller that cannot resolve it before
|
|
@@ -525,6 +538,12 @@ export class GMIManager {
|
|
|
525
538
|
* down first.
|
|
526
539
|
*/
|
|
527
540
|
async resolveGMIForSession(userId, sessionId, requestedPersonaId, conversationIdInput, preferredModelId, preferredProviderId, userApiKeys, agencyOptions, turnOrganizationId) {
|
|
541
|
+
// A seat's session serves its team alone, whatever persona the request names: reusing its GMI would run the
|
|
542
|
+
// request on the team's tools, budget and working memory, and a persona refresh would shut the seat down mid-run.
|
|
543
|
+
// It is checked first, and again after each wait in which a seat could take the session.
|
|
544
|
+
const seatSessionRefused = () => new GMIManagerError(`Session '${sessionId}' is a seat of a team a GMI launched; no request runs in it.`, GMIErrorCode.PERMISSION_DENIED, { sessionId });
|
|
545
|
+
if (this.agencySeatSessions.has(sessionId))
|
|
546
|
+
throw seatSessionRefused();
|
|
528
547
|
const personaDefinition = this.getPersonaDefinition(requestedPersonaId);
|
|
529
548
|
if (!personaDefinition) {
|
|
530
549
|
throw new GMIManagerError(`Persona '${requestedPersonaId}' not found.`, GMIErrorCode.PERSONA_NOT_FOUND, { requestedPersonaId });
|
|
@@ -549,6 +568,8 @@ export class GMIManager {
|
|
|
549
568
|
this.ensureInitialized();
|
|
550
569
|
deactivation = this.deactivations.get(sessionId);
|
|
551
570
|
}
|
|
571
|
+
if (this.agencySeatSessions.has(sessionId))
|
|
572
|
+
throw seatSessionRefused();
|
|
552
573
|
let gmiInstanceId = this.gmiSessionMap.get(sessionId);
|
|
553
574
|
let gmi = gmiInstanceId ? this.activeGMIs.get(gmiInstanceId) : undefined;
|
|
554
575
|
if (gmi && (gmi.getPersona().id !== requestedPersonaId || overlayChanged)) {
|
|
@@ -592,6 +613,11 @@ export class GMIManager {
|
|
|
592
613
|
await this.shutDownGMI(newGMI, newGmiInstanceId, sessionId);
|
|
593
614
|
throw new GMIManagerError(`GMIManager (ID: ${this.managerId}) shut down while GMI ${newGmiInstanceId} was being created for session ${sessionId}.`, GMIErrorCode.NOT_INITIALIZED, { sessionId, gmiInstanceId: newGmiInstanceId });
|
|
594
615
|
}
|
|
616
|
+
if (this.agencySeatSessions.has(sessionId)) {
|
|
617
|
+
// A seat took the session while this GMI was built: it is shut down and never registered.
|
|
618
|
+
await this.shutDownGMI(newGMI, newGmiInstanceId, sessionId);
|
|
619
|
+
throw seatSessionRefused();
|
|
620
|
+
}
|
|
595
621
|
gmi = newGMI;
|
|
596
622
|
this.activeGMIs.set(newGmiInstanceId, gmi);
|
|
597
623
|
this.gmiSessionMap.set(sessionId, newGmiInstanceId);
|
|
@@ -629,6 +655,161 @@ export class GMIManager {
|
|
|
629
655
|
this.ensureInitialized();
|
|
630
656
|
return this.deactivateSession(sessionId);
|
|
631
657
|
}
|
|
658
|
+
agencySeatPromptEngine() {
|
|
659
|
+
const config = this.config.agencySeatPromptEngineConfig;
|
|
660
|
+
if (!config) {
|
|
661
|
+
return Promise.reject(new GMIManagerError('GMIManagerConfig.agencySeatPromptEngineConfig is not set; AgentOS sets it with agencies.', GMIErrorCode.CONFIGURATION_ERROR));
|
|
662
|
+
}
|
|
663
|
+
this.agencySeatEngine ?? (this.agencySeatEngine = (async () => {
|
|
664
|
+
const engine = new PromptEngine();
|
|
665
|
+
// No utility AI: the engine truncates the history and summarizes nothing, so it makes no model call.
|
|
666
|
+
await engine.initialize(config);
|
|
667
|
+
return engine;
|
|
668
|
+
})().catch((error) => {
|
|
669
|
+
this.agencySeatEngine = undefined;
|
|
670
|
+
throw error;
|
|
671
|
+
}));
|
|
672
|
+
return this.agencySeatEngine;
|
|
673
|
+
}
|
|
674
|
+
/** A seat's persona: the definition a launch made, or a registered one the user may use. */
|
|
675
|
+
async agencySeatPersona(spec) {
|
|
676
|
+
if ('definition' in spec.persona)
|
|
677
|
+
return normalizePersonaDefinition(spec.persona.definition);
|
|
678
|
+
const personaId = spec.persona.personaId;
|
|
679
|
+
const persona = this.getPersonaDefinition(personaId);
|
|
680
|
+
if (!persona) {
|
|
681
|
+
throw new GMIManagerError(`Persona '${personaId}' not found.`, GMIErrorCode.PERSONA_NOT_FOUND, { personaId });
|
|
682
|
+
}
|
|
683
|
+
const record = this.allPersonaRecords.get(personaId);
|
|
684
|
+
const strict = this.config.personaValidationStrict;
|
|
685
|
+
if (strict?.enabled && !strict.shadowMode && record?.status === 'invalid') {
|
|
686
|
+
throw new GMIManagerError(`Persona '${personaId}' is invalid and blocked by strict validation.`, GMIErrorCode.PERMISSION_DENIED, { personaId });
|
|
687
|
+
}
|
|
688
|
+
if (!(await this.userMeetsPersonaTier(spec.userId, persona))) {
|
|
689
|
+
throw new GMIManagerError(`Access denied: Persona '${personaId}' requires tier '${persona.minSubscriptionTier}'.`, GMIErrorCode.PERMISSION_DENIED, { personaId, userId: spec.userId });
|
|
690
|
+
}
|
|
691
|
+
return persona;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Builds and registers the GMI of one seat of a team a GMI launched (`launch_agency` on the full runtime): the
|
|
695
|
+
* registered persona a `personaId` seat names, checked as a session's persona is (strict validation, the user's
|
|
696
|
+
* tier), or the definition the launch made for a temporary seat. The GMI has no cognitive memory and no retrieval
|
|
697
|
+
* augmentor (its input is a manager's or a sibling's text), a prompt engine and a statistical utility that
|
|
698
|
+
* make no model call, the tool view and provider manager the launch gives it, and, with the runtime's learning layer,
|
|
699
|
+
* no learner (a workflow seat's source): it still renders its persona's traits, and with the layer off it sends no
|
|
700
|
+
* personality section. It is registered under the seat session id, so its own tool calls resolve it; `release()`
|
|
701
|
+
* shuts it down and takes it out of the manager, and a handle released after the manager shut down leaves alone
|
|
702
|
+
* whatever holds the session since. Until then the session is the seat's:
|
|
703
|
+
* `getOrCreateGMIForSession()` refuses it with `PERMISSION_DENIED`, whatever persona the request names (a request
|
|
704
|
+
* whose GMI was being built when the seat took the session included, that GMI shut down unregistered),
|
|
705
|
+
* `processUserFeedback()` records nothing for it and `cleanupInactiveGMIs()` passes it by. `shutdown()` waits for a
|
|
706
|
+
* seat being built, as it waits for a session's GMI, and the build then fails with its GMI shut down.
|
|
707
|
+
*
|
|
708
|
+
* @throws {GMIManagerError} `PERSONA_NOT_FOUND` for an unknown persona; `PERMISSION_DENIED` for one the user's tier or
|
|
709
|
+
* strict validation refuses; `INVALID_STATE` for a session that already has a GMI; `CONFIGURATION_ERROR` without
|
|
710
|
+
* `agencySeatPromptEngineConfig`; `NOT_INITIALIZED` when the manager is not, or shuts down while the seat is built.
|
|
711
|
+
* @throws {GMIError} `GMI_INITIALIZATION_ERROR` when the GMI does not initialize.
|
|
712
|
+
*/
|
|
713
|
+
async createAgencySeat(spec) {
|
|
714
|
+
this.ensureInitialized();
|
|
715
|
+
// shutdown() waits for this build to settle, as it waits for a session's; a GMI the build makes once shutdown has
|
|
716
|
+
// begun is shut down instead of registered.
|
|
717
|
+
let settle;
|
|
718
|
+
const inFlight = new Promise((resolve) => {
|
|
719
|
+
settle = resolve;
|
|
720
|
+
});
|
|
721
|
+
this.creationsInFlight.add(inFlight);
|
|
722
|
+
try {
|
|
723
|
+
return await this.buildAgencySeat(spec);
|
|
724
|
+
}
|
|
725
|
+
finally {
|
|
726
|
+
this.creationsInFlight.delete(inFlight);
|
|
727
|
+
settle();
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
/** The work of {@link GMIManager.createAgencySeat}. */
|
|
731
|
+
async buildAgencySeat(spec) {
|
|
732
|
+
const taken = () => new GMIManagerError(`Session '${spec.seatSessionId}' already has a GMI; a seat runs in a session of its own.`, GMIErrorCode.INVALID_STATE, { sessionId: spec.seatSessionId });
|
|
733
|
+
if (this.gmiSessionMap.has(spec.seatSessionId))
|
|
734
|
+
throw taken();
|
|
735
|
+
const persona = await this.agencySeatPersona(spec);
|
|
736
|
+
const promptEngine = await this.agencySeatPromptEngine();
|
|
737
|
+
const gmiInstanceId = `gmi-instance-${uuidv4()}`;
|
|
738
|
+
const utilityAI = new StatisticalUtilityAI(`agency-seat-utility-${gmiInstanceId}`);
|
|
739
|
+
await utilityAI.initialize({ utilityId: `agency-seat-utility-${gmiInstanceId}` });
|
|
740
|
+
const config = {
|
|
741
|
+
workingMemory: new InMemoryWorkingMemory(),
|
|
742
|
+
promptEngine,
|
|
743
|
+
llmProviderManager: spec.providerManager ? spec.providerManager(this.llmProviderManager) : this.llmProviderManager,
|
|
744
|
+
utilityAI,
|
|
745
|
+
toolOrchestrator: spec.toolView(this.toolOrchestrator),
|
|
746
|
+
defaultLlmProviderId: persona.defaultProviderId || this.config.defaultGMIBaseConfigDefaults?.defaultLlmProviderId,
|
|
747
|
+
defaultLlmModelId: persona.defaultModelId || this.config.defaultGMIBaseConfigDefaults?.defaultLlmModelId,
|
|
748
|
+
defaultReasoningTraceMaxEntries: this.config.defaultGMIBaseConfigDefaults?.defaultReasoningTraceMaxEntries,
|
|
749
|
+
defaultReasoningTraceMaxMessageLength: this.config.defaultGMIBaseConfigDefaults?.defaultReasoningTraceMaxMessageLength,
|
|
750
|
+
customSettings: persona.customFields,
|
|
751
|
+
// A GMI waits as long for the turns its shutdown stops as the manager waits for the GMI.
|
|
752
|
+
shutdownTimeoutMs: this.config.shutdownTimeoutMs,
|
|
753
|
+
...(spec.maxToolLoopIterations !== undefined ? { maxToolLoopIterations: spec.maxToolLoopIterations } : {}),
|
|
754
|
+
// A workflow seat's source: with a learning layer, the seat's turns have no learner.
|
|
755
|
+
...(await this.assembleLearning(persona, { gmiInstanceId, sessionId: spec.seatSessionId, userId: spec.userId }, { registryPersona: persona, workflowSeat: true })),
|
|
756
|
+
};
|
|
757
|
+
const gmi = new GMI(gmiInstanceId);
|
|
758
|
+
try {
|
|
759
|
+
await gmi.initialize(persona, config);
|
|
760
|
+
}
|
|
761
|
+
catch (error) {
|
|
762
|
+
// The GMI never runs, so the learner session made for it ends here; a failure to end it is not the error.
|
|
763
|
+
await Promise.resolve()
|
|
764
|
+
.then(() => config.learning?.endSession())
|
|
765
|
+
.catch(() => undefined);
|
|
766
|
+
throw createGMIErrorFromError(error, GMIErrorCode.GMI_INITIALIZATION_ERROR, { gmiInstanceId }, `Failed to initialize the agency seat GMI ${gmiInstanceId}.`);
|
|
767
|
+
}
|
|
768
|
+
if (!this.isInitialized) {
|
|
769
|
+
// shutdown() began while the seat was built: it is shut down here and never registered.
|
|
770
|
+
await this.shutDownGMI(gmi, gmiInstanceId, spec.seatSessionId);
|
|
771
|
+
throw new GMIManagerError(`GMIManager (ID: ${this.managerId}) shut down while the agency seat ${spec.seatSessionId} was being created.`, GMIErrorCode.NOT_INITIALIZED, { sessionId: spec.seatSessionId });
|
|
772
|
+
}
|
|
773
|
+
if (this.gmiSessionMap.has(spec.seatSessionId)) {
|
|
774
|
+
// Another build took the session while this one ran: this GMI is shut down and never registered.
|
|
775
|
+
await this.shutDownGMI(gmi, gmiInstanceId, spec.seatSessionId);
|
|
776
|
+
throw taken();
|
|
777
|
+
}
|
|
778
|
+
this.activeGMIs.set(gmiInstanceId, gmi);
|
|
779
|
+
this.gmiSessionMap.set(spec.seatSessionId, gmiInstanceId);
|
|
780
|
+
this.agencySeatSessions.set(spec.seatSessionId, gmiInstanceId);
|
|
781
|
+
let released;
|
|
782
|
+
return {
|
|
783
|
+
gmi,
|
|
784
|
+
personaId: persona.id,
|
|
785
|
+
// Once: a second call waits for the first. It skips the initialization check, so a seat closed while the manager
|
|
786
|
+
// shuts down is still released. The session is the seat's until its GMI is gone.
|
|
787
|
+
release: () => (released ?? (released = this.releaseAgencySeat(spec.seatSessionId, gmiInstanceId, gmi))),
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Releases one seat's GMI and then its hold on the session. Only the seat's own GMI and hold go: once the manager has
|
|
792
|
+
* shut down, the session may hold a GMI or a seat that came after it, which stays.
|
|
793
|
+
*/
|
|
794
|
+
async releaseAgencySeat(sessionId, gmiInstanceId, gmi) {
|
|
795
|
+
try {
|
|
796
|
+
if (this.gmiSessionMap.get(sessionId) === gmiInstanceId) {
|
|
797
|
+
await this.deactivateSession(sessionId);
|
|
798
|
+
}
|
|
799
|
+
else if (this.activeGMIs.get(gmiInstanceId) === gmi) {
|
|
800
|
+
try {
|
|
801
|
+
await this.shutDownGMI(gmi, gmiInstanceId, sessionId);
|
|
802
|
+
}
|
|
803
|
+
finally {
|
|
804
|
+
this.activeGMIs.delete(gmiInstanceId);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
finally {
|
|
809
|
+
if (this.agencySeatSessions.get(sessionId) === gmiInstanceId)
|
|
810
|
+
this.agencySeatSessions.delete(sessionId);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
632
813
|
/**
|
|
633
814
|
* Shuts down the GMI bound to a session and removes it from both maps. It
|
|
634
815
|
* skips the initialization check because `shutdown()` marks the manager
|
|
@@ -713,9 +894,9 @@ export class GMIManager {
|
|
|
713
894
|
}
|
|
714
895
|
}
|
|
715
896
|
/**
|
|
716
|
-
* Waits, at most `shutdownTimeoutMs`, for the getOrCreateGMIForSession()
|
|
717
|
-
* calls in flight to settle. A call still running after
|
|
718
|
-
* GMI it builds once it gets that far.
|
|
897
|
+
* Waits, at most `shutdownTimeoutMs`, for the getOrCreateGMIForSession() and
|
|
898
|
+
* createAgencySeat() calls in flight to settle. A call still running after
|
|
899
|
+
* that shuts down the GMI it builds once it gets that far.
|
|
719
900
|
*/
|
|
720
901
|
async creationsSettled() {
|
|
721
902
|
if (this.creationsInFlight.size === 0)
|
|
@@ -734,6 +915,9 @@ export class GMIManager {
|
|
|
734
915
|
const thresholdMs = threshold * 60 * 1000;
|
|
735
916
|
const sessionIdsSnapshot = Array.from(this.gmiSessionMap.keys());
|
|
736
917
|
for (const sessionId of sessionIdsSnapshot) {
|
|
918
|
+
// A seat's GMI lives as long as its launch, which releases it; its turns leave no conversation context here.
|
|
919
|
+
if (this.agencySeatSessions.has(sessionId))
|
|
920
|
+
continue;
|
|
737
921
|
const gmiInstanceId = this.gmiSessionMap.get(sessionId);
|
|
738
922
|
if (!gmiInstanceId)
|
|
739
923
|
continue;
|
|
@@ -779,9 +963,9 @@ export class GMIManager {
|
|
|
779
963
|
this.isInitialized = false;
|
|
780
964
|
// Every GMI shuts down at the same time, each within shutdownTimeoutMs, so
|
|
781
965
|
// the manager takes about one bound however many GMIs are active. In the
|
|
782
|
-
// same bound it waits for the getOrCreateGMIForSession()
|
|
783
|
-
// one that began before the flag was
|
|
784
|
-
// GMI shuts that GMI down itself.
|
|
966
|
+
// same bound it waits for the getOrCreateGMIForSession() and
|
|
967
|
+
// createAgencySeat() calls in flight: one that began before the flag was
|
|
968
|
+
// cleared and has not registered its GMI shuts that GMI down itself.
|
|
785
969
|
const sessionIdsToDeactivate = Array.from(this.gmiSessionMap.keys());
|
|
786
970
|
// A GMI in the active map that no session maps to is shut down in the same
|
|
787
971
|
// pass. Two creations for one new session that race both build a GMI, and
|
|
@@ -797,12 +981,15 @@ export class GMIManager {
|
|
|
797
981
|
]);
|
|
798
982
|
this.activeGMIs.clear();
|
|
799
983
|
this.gmiSessionMap.clear();
|
|
984
|
+
this.agencySeatSessions.clear();
|
|
800
985
|
this.allPersonaDefinitions.clear();
|
|
801
986
|
console.log(`GMIManager (ID: ${this.managerId}): Shutdown complete.`);
|
|
802
987
|
}
|
|
803
988
|
/**
|
|
804
|
-
* Routes user feedback to the GMI that serves the session
|
|
805
|
-
*
|
|
989
|
+
* Routes user feedback to the GMI that serves the session; feedback that
|
|
990
|
+
* names the session of a seat of a launched team (createAgencySeat()) is not
|
|
991
|
+
* recorded. The payload is normalized first (see
|
|
992
|
+
* {@link normalizeUserFeedback}): a `rating` label
|
|
806
993
|
* decides the polarity, otherwise a numeric rating is read on the 1 to 5
|
|
807
994
|
* scale. The GMI then records a trace entry and, when cognitive memory is
|
|
808
995
|
* configured, stores the feedback and any correction as memories of the user.
|
|
@@ -818,6 +1005,10 @@ export class GMIManager {
|
|
|
818
1005
|
fields: feedbackData && typeof feedbackData === 'object' ? Object.keys(feedbackData) : [],
|
|
819
1006
|
textLength: typeof feedbackData?.text === 'string' ? feedbackData.text.length : 0,
|
|
820
1007
|
});
|
|
1008
|
+
// A seat's GMI serves its team alone: feedback that names its session reaches neither the GMI nor its trace, which
|
|
1009
|
+
// the GMI's self-reflection reads.
|
|
1010
|
+
if (this.agencySeatSessions.has(sessionId))
|
|
1011
|
+
return;
|
|
821
1012
|
const gmiInstanceId = this.gmiSessionMap.get(sessionId);
|
|
822
1013
|
const gmi = gmiInstanceId ? this.activeGMIs.get(gmiInstanceId) : undefined;
|
|
823
1014
|
if (!gmi || !feedbackData || typeof feedbackData !== 'object') {
|