glove-foundry 0.5.0 → 0.5.2
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/README.md +27 -15
- package/dist/{chunk-KBMD4RYU.js → chunk-6Q2LGPSC.js} +49 -198
- package/dist/{chunk-GKZLWD5M.js → chunk-7F7QVO6I.js} +4 -1
- package/dist/{chunk-SGF3CFUR.js → chunk-D2AHSYOB.js} +71 -8
- package/dist/{chunk-TH5ETCG2.js → chunk-MABLKZVO.js} +13 -4
- package/dist/{chunk-LW5PJ2FN.js → chunk-NHV64WNO.js} +1 -1
- package/dist/{chunk-5NFLGHOC.js → chunk-PVOKR4CN.js} +211 -29
- package/dist/cli.js +7 -5
- package/dist/{client-DcsnudMI.d.ts → client-CLTds1uV.d.ts} +13 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/execution-agent.js +4 -4
- package/dist/execution-daemon.js +1 -1
- package/dist/execution-loader.js +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +14 -14
- package/docs/building-with-foundry.md +4 -2
- package/docs/release-verification.md +1 -1
- package/package.json +9 -9
- package/templates/minimal/README.md +34 -8
- package/templates/minimal/agents/assistant/agent.ts +24 -10
- package/templates/minimal/foundry.application.ts +11 -3
- package/templates/minimal/gitignore +1 -0
- package/templates/minimal/lib/file-store.ts +95 -0
- package/templates/travel-concierge/README.md +46 -12
- package/templates/travel-concierge/agents/concierge/agent.ts +10 -4
- package/templates/travel-concierge/agents/concierge/composition.ts +9 -2
- package/templates/travel-concierge/agents/concierge/flights.ts +43 -0
- package/templates/travel-concierge/agents/concierge/instances.ts +42 -0
- package/templates/travel-concierge/agents/concierge/memory/traveller.memory.ts +13 -8
- package/templates/travel-concierge/agents/concierge/tools/convert-currency.tool.ts +34 -0
- package/templates/travel-concierge/agents/concierge/workbench.ts +4 -1
- package/templates/travel-concierge/foundry.application.ts +15 -6
- package/templates/travel-concierge/gitignore +1 -0
- package/templates/travel-concierge/lib/demo-model.ts +89 -25
- package/templates/travel-concierge/lib/file-context.ts +60 -0
- package/templates/travel-concierge/lib/file-store.ts +95 -0
- package/templates/minimal/agents/assistant/tools/current-time.tool.ts +0 -17
- package/templates/travel-concierge/agents/concierge/tools/find-flights.tool.ts +0 -49
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FoundryDataAdapter, E as EnvironmentValue, A as AgentInstance, C as Conversation, P as PlaybookSubscription, a as FoundryActivationRecord, b as ProvisionAgentOptions, I as InboundDeliveryClaim, W as WorkspaceEntry, c as FoundryWorkingEnvironmentSnapshotOwner, S as SharedInboxItem, d as FoundryTask, e as AgentPlaybook, f as FoundryRuntime, D as DiscoveredAgent, g as FoundryManifest, h as AnyFoundryTransmission, i as AccountReference, j as InferAccountMetadata, k as AgentBinding, l as FoundryAgentApplication, m as InboundRoute, O as OutboundRoute, n as CapabilityDefinition, o as InferInboundConfig, p as InferOutboundConfig } from './client-
|
|
2
|
-
export { q as AccountContract, r as AccountDirectory, s as AccountFilter, t as AccountId, u as AccountNotFound, v as AccountSessionAdapter, w as AccountSessionRequest, x as AccountSessionUnavailable, y as AccountSummary, z as AgentApplicationContribution, B as AgentApplicationInstallContext, G as AgentApplicationOptions, H as AgentAssemblyContext, J as AgentAssemblyOptions, K as AgentDefinitionId, L as AgentDefinitionSurfaceContext, M as AgentFactoryContext, N as AgentHandlerContext, Q as AgentId, R as AgentInstallContext, T as AgentInstallation, U as AgentInstallationKind, V as AgentPlaybookInput, X as AgentProvisioningPolicy, Y as AgentRuntimeControls, Z as AnyFoundryAgent, _ as ApplicationConnectionContext, $ as ApplicationConnectionState, a0 as ApplicationConnectionStatus, a1 as BindingFilter, a2 as BindingId, a3 as BindingNotFound, a4 as CapabilityId, a5 as ComposedAgentPlaybook, a6 as ComposedAgentPlaybookInput, a7 as ConnectionReceiveInput, a8 as CreateAgentInstanceOptions, a9 as CreateConversationOptions, aa as CustomProvisionedAgent, ab as CustomProvisioningContext, ac as DefineAgentOptions, ad as DefineConnectionOptions, ae as DefineFoundryReplOptions, af as DefineFoundryScheduleOptions, ag as DefineFoundrySubagentOptions, ah as DefineFoundryWorkingEnvironmentOptions, ai as DefinePlaybookSubscriptionOptions, aj as DefinitionConfigInput, ak as EMPTY_AGENT_COMPOSITION, al as EMPTY_CAPABILITY_REGISTRY, am as EMPTY_FOUNDRY_APPLICATION, an as EMPTY_NATIVE_REGISTRY, ao as EgressAdapter, ap as EgressContext, aq as EventFilter, ar as EventId, as as EventNotFound, at as EventReference, au as EventStore, av as FOUNDRY_AGENT_APPLICATION_BRAND, aw as FOUNDRY_AGENT_BRAND, ax as FOUNDRY_AGENT_DEFINITION_BRAND, ay as FOUNDRY_AGENT_FILE_ENV, az as FOUNDRY_AGENT_ROUTE_ENV, aA as FOUNDRY_APPLICATION_BRAND, aB as FOUNDRY_APPLICATION_ENV, aC as FOUNDRY_APPROVAL_DIRECTORY_ENV, aD as FOUNDRY_COMPOSED_PLAYBOOK_BRAND, aE as FOUNDRY_CONNECTION_BRAND, aF as FOUNDRY_CORE_COMMAND_EVENT, aG as FOUNDRY_EVENT_PREFIX, aH as FOUNDRY_EXECUTION_MARKER, aI as FOUNDRY_LAYER_BRAND, aJ as FOUNDRY_MCP_BRAND, aK as FOUNDRY_MEMORY_BRAND, aL as FOUNDRY_PLAYBOOK_ACTION_BRAND, aM as FOUNDRY_REPL_BRAND, aN as FOUNDRY_SCHEDULE_BRAND, aO as FOUNDRY_SHARED_TOOL_BRAND, aP as FOUNDRY_SUBSCRIBER_BRAND, aQ as FOUNDRY_TRANSMISSION_BRAND, aR as FOUNDRY_TRANSMISSION_EVENT_BRAND, aS as FOUNDRY_TRANSMISSION_PREDICATE_BRAND, aT as FOUNDRY_WORKING_ENVIRONMENT_BRAND, aU as FoundryAccountSessionAdapter, aV as FoundryAgent, aW as FoundryAgentComponent, aX as FoundryAgentComposition, aY as FoundryAgentConventionModule, aZ as FoundryAgentDefinition, a_ as FoundryAgentMode, a$ as FoundryApp, b0 as FoundryApplication, b1 as FoundryApplicationConnection, b2 as FoundryApplicationManifest, b3 as FoundryApplicationOptions, b4 as FoundryApproval, b5 as FoundryApprovalDecision, b6 as FoundryApprovalDisplayManager, b7 as FoundryApprovalStatus, b8 as FoundryCall, b9 as FoundryCallContext, ba as FoundryCallOptions, bb as FoundryCapabilityKind, bc as FoundryCapabilityManifest, bd as FoundryCapabilityManifestEntry, be as FoundryCapabilityRegistry, bf as FoundryClient, bg as FoundryClientAuthorizationAdapter, bh as FoundryClientOptions, bi as FoundryCompositionSource, bj as FoundryConversationTranscript, bk as FoundryCoreCommand, bl as FoundryDomainError, bm as FoundryEvent, bn as FoundryEventCategory, bo as FoundryExecutionContext, bp as FoundryFactsOptions, bq as FoundryFormsOptions, br as FoundryGoalsOptions, bs as FoundryGuidanceHandles, bt as FoundryGuidanceScope, bu as FoundryHealth, bv as FoundryHookDefinition, bw as FoundryInstallable, bx as FoundryInstanceProvisioner, by as FoundryJavaScriptReplDefinition, bz as FoundryLayer, bA as FoundryLayerOptions, bB as FoundryLayerReference, bC as FoundryLayerSelection, bD as FoundryLispReplDefinition, bE as FoundryListResolver, bF as FoundryManifestAgent, bG as FoundryManifestCapability, bH as FoundryManifestTransmission, bI as FoundryMcp, bJ as FoundryMcpOptions, bK as FoundryMemoryProfile, bL as FoundryMemoryProfileOptions, bM as FoundryMemoryReference, bN as FoundryMemorySelection, bO as FoundryMeshConfig, bP as FoundryMessageInput, bQ as FoundryMountedRepl, bR as FoundryNativeManifest, bS as FoundryNativeManifestEntry, bT as FoundryNativeRegistry, bU as FoundryObservabilityAdapter, bV as FoundryPlaybookAction, bW as FoundryProgrammaticToolContext, bX as FoundryProgrammaticToolSelection, bY as FoundryProgrammaticTools, bZ as FoundryPythonReplDefinition, b_ as FoundryReplDefinition, b$ as FoundryRequest, c0 as FoundryRequestAuthorizationAdapter, c1 as FoundryRequestAuthorizationInput, c2 as FoundryResolvedMcp, c3 as FoundryResolver, c4 as FoundryResult, c5 as FoundryRouteMap, c6 as FoundryRun, c7 as FoundryRunHandle, c8 as FoundryRuntimeError, c9 as FoundryRuntimeOptions, ca as FoundryScheduleDefinition, cb as FoundryScheduleTiming, cc as FoundryScheduleTimingInput, cd as FoundrySharedTool, ce as FoundrySteerHandleResult, cf as FoundrySteerResult, cg as FoundrySubagentToolContext, ch as FoundrySubscriber, ci as FoundrySubscriberOptions, cj as FoundrySubscriberSelection, ck as FoundrySurfaceContext, cl as FoundryToolBody, cm as FoundryTransmission, cn as FoundryTransmissionEvent, co as FoundryTransmissionPredicate, cp as FoundryVfs, cq as FoundryVfsHandle, cr as FoundryWorkingEnvironmentCreateContext, cs as FoundryWorkingEnvironmentDefinition, ct as FoundryWorkingEnvironmentPersistenceAdapter, cu as FoundryWorkingEnvironmentPersistenceContext, cv as GrantResolutionError, cw as GrantResolver, cx as InboundContract, cy as InferAgentInput, cz as InferAgentOutput, cA as InferInboundEvent, cB as InferOutboundInput, cC as InferOutboundOutput, cD as IngressAdapter, cE as IngressContext, cF as InstallationSelection, cG as ManifestCompilationError, cH as McpAdapterFactory, cI as MemoryFoundryDataAdapter, cJ as MemoryObservabilityAdapter, cK as OutboundContract, cL as PlaybookActionOptions, cM as PlaybookDirective, cN as PlaybookDirectiveInput, cO as PlaybookMatch, cP as PlaybookMatchInput, cQ as PlaybookOutboundDirective, cR as PlaybookOutboundInput, cS as PlaybookSubscriptionTarget, cT as PlaybookSubscriptionTargetInput, cU as ReplyPolicy, cV as ResolveGrantRequest, cW as Route, cX as RouteFilter, cY as RouteId, cZ as RouteNotFound, c_ as RunGrant, c$ as RunId, d0 as SharedToolOptions, d1 as TopologyConflict, d2 as TopologyStore, d3 as TransmissionEventDirection, d4 as TransmissionEventOptions, d5 as TransmissionId, d6 as TransmissionOptions, d7 as TransmissionPredicateOptions, d8 as TransmissionSerializationContext, d9 as UpdateAgentInstanceOptions, da as UpdateConversationOptions, db as WaitOptions, dc as compileApplicationManifest, dd as composeAgent, de as composePlaybook, df as configureLayer, dg as configureMemory, dh as createAgentInstance, di as createConversation, dj as createFoundryApproval, dk as createFoundryClient, dl as createFoundryCoreTools, dm as createInstalledApplicationTransmissionTools, dn as createManifest, dp as defineAgent, dq as defineAgentApplication, dr as defineAgentFromModule, ds as defineAgentInstance, dt as defineApp, du as defineApplication, dv as defineCall, dw as defineConnection, dx as defineFacts, dy as defineForms, dz as defineGoals, dA as defineLayer, dB as defineMcp, dC as defineMemory, dD as definePlaybookAction, dE as definePlaybookSubscription, dF as defineRepl, dG as defineRoutes, dH as defineSchedule, dI as defineSharedTool, dJ as defineSubagent, dK as defineSubscriber, dL as defineTransmission, dM as defineTransmissionEvent, dN as defineTransmissionPredicate, dO as defineWorkingEnvironment, dP as discoverAgents, dQ as findAgentFiles, dR as foundryDataEnvironmentPersistence, dS as foundryGuidanceSubject, dT as grantResolverLive, dU as install, dV as installRegistry, dW as installationKey, dX as installedApplicationTransmissionToolName, dY as internalAgentName, dZ as isFoundryAgent, d_ as isFoundryAgentDefinition, d$ as isFoundryApplication, e0 as isFoundryCapability, e1 as isFoundryLayer, e2 as isFoundrySchedule, e3 as isFoundrySubscriber, e4 as isFoundryTransmission, e5 as isInboxCapableStore, e6 as listFoundryApprovals, e7 as memoryAccountDirectory, e8 as memoryEventStore, e9 as memoryTopologyStore, ea as mountAgentDefinitionMemory, eb as mountFoundrySurfaces, ec as reconstructAgentInstance, ed as reconstructPlaybook, ee as reconstructPlaybookSubscription, ef as resolveFoundryApproval, eg as routeFromAgentFile, eh as routeFromInternalAgentName, ei as toGloveMessage, ej as toGloveRequestInput, ek as transmissionPredicate, el as withFoundryPermissions } from './client-
|
|
1
|
+
import { F as FoundryDataAdapter, E as EnvironmentValue, A as AgentInstance, C as Conversation, P as PlaybookSubscription, a as FoundryActivationRecord, b as ProvisionAgentOptions, I as InboundDeliveryClaim, W as WorkspaceEntry, c as FoundryWorkingEnvironmentSnapshotOwner, S as SharedInboxItem, d as FoundryTask, e as AgentPlaybook, f as FoundryRuntime, D as DiscoveredAgent, g as FoundryManifest, h as AnyFoundryTransmission, i as AccountReference, j as InferAccountMetadata, k as AgentBinding, l as FoundryAgentApplication, m as InboundRoute, O as OutboundRoute, n as CapabilityDefinition, o as InferInboundConfig, p as InferOutboundConfig } from './client-CLTds1uV.js';
|
|
2
|
+
export { q as AccountContract, r as AccountDirectory, s as AccountFilter, t as AccountId, u as AccountNotFound, v as AccountSessionAdapter, w as AccountSessionRequest, x as AccountSessionUnavailable, y as AccountSummary, z as AgentApplicationContribution, B as AgentApplicationInstallContext, G as AgentApplicationOptions, H as AgentAssemblyContext, J as AgentAssemblyOptions, K as AgentDefinitionId, L as AgentDefinitionSurfaceContext, M as AgentFactoryContext, N as AgentHandlerContext, Q as AgentId, R as AgentInstallContext, T as AgentInstallation, U as AgentInstallationKind, V as AgentPlaybookInput, X as AgentProvisioningPolicy, Y as AgentRuntimeControls, Z as AnyFoundryAgent, _ as ApplicationConnectionContext, $ as ApplicationConnectionState, a0 as ApplicationConnectionStatus, a1 as BindingFilter, a2 as BindingId, a3 as BindingNotFound, a4 as CapabilityId, a5 as ComposedAgentPlaybook, a6 as ComposedAgentPlaybookInput, a7 as ConnectionReceiveInput, a8 as CreateAgentInstanceOptions, a9 as CreateConversationOptions, aa as CustomProvisionedAgent, ab as CustomProvisioningContext, ac as DefineAgentOptions, ad as DefineConnectionOptions, ae as DefineFoundryReplOptions, af as DefineFoundryScheduleOptions, ag as DefineFoundrySubagentOptions, ah as DefineFoundryWorkingEnvironmentOptions, ai as DefinePlaybookSubscriptionOptions, aj as DefinitionConfigInput, ak as EMPTY_AGENT_COMPOSITION, al as EMPTY_CAPABILITY_REGISTRY, am as EMPTY_FOUNDRY_APPLICATION, an as EMPTY_NATIVE_REGISTRY, ao as EgressAdapter, ap as EgressContext, aq as EventFilter, ar as EventId, as as EventNotFound, at as EventReference, au as EventStore, av as FOUNDRY_AGENT_APPLICATION_BRAND, aw as FOUNDRY_AGENT_BRAND, ax as FOUNDRY_AGENT_DEFINITION_BRAND, ay as FOUNDRY_AGENT_FILE_ENV, az as FOUNDRY_AGENT_ROUTE_ENV, aA as FOUNDRY_APPLICATION_BRAND, aB as FOUNDRY_APPLICATION_ENV, aC as FOUNDRY_APPROVAL_DIRECTORY_ENV, aD as FOUNDRY_COMPOSED_PLAYBOOK_BRAND, aE as FOUNDRY_CONNECTION_BRAND, aF as FOUNDRY_CORE_COMMAND_EVENT, aG as FOUNDRY_EVENT_PREFIX, aH as FOUNDRY_EXECUTION_MARKER, aI as FOUNDRY_LAYER_BRAND, aJ as FOUNDRY_MCP_BRAND, aK as FOUNDRY_MEMORY_BRAND, aL as FOUNDRY_PLAYBOOK_ACTION_BRAND, aM as FOUNDRY_REPL_BRAND, aN as FOUNDRY_SCHEDULE_BRAND, aO as FOUNDRY_SHARED_TOOL_BRAND, aP as FOUNDRY_SUBSCRIBER_BRAND, aQ as FOUNDRY_TRANSMISSION_BRAND, aR as FOUNDRY_TRANSMISSION_EVENT_BRAND, aS as FOUNDRY_TRANSMISSION_PREDICATE_BRAND, aT as FOUNDRY_WORKING_ENVIRONMENT_BRAND, aU as FoundryAccountSessionAdapter, aV as FoundryAgent, aW as FoundryAgentComponent, aX as FoundryAgentComposition, aY as FoundryAgentConventionModule, aZ as FoundryAgentDefinition, a_ as FoundryAgentMode, a$ as FoundryApp, b0 as FoundryApplication, b1 as FoundryApplicationConnection, b2 as FoundryApplicationManifest, b3 as FoundryApplicationOptions, b4 as FoundryApproval, b5 as FoundryApprovalDecision, b6 as FoundryApprovalDisplayManager, b7 as FoundryApprovalStatus, b8 as FoundryCall, b9 as FoundryCallContext, ba as FoundryCallOptions, bb as FoundryCapabilityKind, bc as FoundryCapabilityManifest, bd as FoundryCapabilityManifestEntry, be as FoundryCapabilityRegistry, bf as FoundryClient, bg as FoundryClientAuthorizationAdapter, bh as FoundryClientOptions, bi as FoundryCompositionSource, bj as FoundryConversationTranscript, bk as FoundryCoreCommand, bl as FoundryDomainError, bm as FoundryEvent, bn as FoundryEventCategory, bo as FoundryExecutionContext, bp as FoundryFactsOptions, bq as FoundryFormsOptions, br as FoundryGoalsOptions, bs as FoundryGuidanceHandles, bt as FoundryGuidanceScope, bu as FoundryHealth, bv as FoundryHookDefinition, bw as FoundryInstallable, bx as FoundryInstanceProvisioner, by as FoundryJavaScriptReplDefinition, bz as FoundryLayer, bA as FoundryLayerOptions, bB as FoundryLayerReference, bC as FoundryLayerSelection, bD as FoundryLispReplDefinition, bE as FoundryListResolver, bF as FoundryManifestAgent, bG as FoundryManifestCapability, bH as FoundryManifestTransmission, bI as FoundryMcp, bJ as FoundryMcpOptions, bK as FoundryMemoryProfile, bL as FoundryMemoryProfileOptions, bM as FoundryMemoryReference, bN as FoundryMemorySelection, bO as FoundryMeshConfig, bP as FoundryMessageInput, bQ as FoundryMountedRepl, bR as FoundryNativeManifest, bS as FoundryNativeManifestEntry, bT as FoundryNativeRegistry, bU as FoundryObservabilityAdapter, bV as FoundryPlaybookAction, bW as FoundryProgrammaticToolContext, bX as FoundryProgrammaticToolSelection, bY as FoundryProgrammaticTools, bZ as FoundryPythonReplDefinition, b_ as FoundryReplDefinition, b$ as FoundryRequest, c0 as FoundryRequestAuthorizationAdapter, c1 as FoundryRequestAuthorizationInput, c2 as FoundryResolvedMcp, c3 as FoundryResolver, c4 as FoundryResult, c5 as FoundryRouteMap, c6 as FoundryRun, c7 as FoundryRunHandle, c8 as FoundryRuntimeError, c9 as FoundryRuntimeOptions, ca as FoundryScheduleDefinition, cb as FoundryScheduleTiming, cc as FoundryScheduleTimingInput, cd as FoundrySharedTool, ce as FoundrySteerHandleResult, cf as FoundrySteerResult, cg as FoundrySubagentToolContext, ch as FoundrySubscriber, ci as FoundrySubscriberOptions, cj as FoundrySubscriberSelection, ck as FoundrySurfaceContext, cl as FoundryToolBody, cm as FoundryTransmission, cn as FoundryTransmissionEvent, co as FoundryTransmissionPredicate, cp as FoundryVfs, cq as FoundryVfsHandle, cr as FoundryWorkingEnvironmentCreateContext, cs as FoundryWorkingEnvironmentDefinition, ct as FoundryWorkingEnvironmentPersistenceAdapter, cu as FoundryWorkingEnvironmentPersistenceContext, cv as GrantResolutionError, cw as GrantResolver, cx as InboundContract, cy as InferAgentInput, cz as InferAgentOutput, cA as InferInboundEvent, cB as InferOutboundInput, cC as InferOutboundOutput, cD as IngressAdapter, cE as IngressContext, cF as InstallationSelection, cG as ManifestCompilationError, cH as McpAdapterFactory, cI as MemoryFoundryDataAdapter, cJ as MemoryObservabilityAdapter, cK as OutboundContract, cL as PlaybookActionOptions, cM as PlaybookDirective, cN as PlaybookDirectiveInput, cO as PlaybookMatch, cP as PlaybookMatchInput, cQ as PlaybookOutboundDirective, cR as PlaybookOutboundInput, cS as PlaybookSubscriptionTarget, cT as PlaybookSubscriptionTargetInput, cU as ReplyPolicy, cV as ResolveGrantRequest, cW as Route, cX as RouteFilter, cY as RouteId, cZ as RouteNotFound, c_ as RunGrant, c$ as RunId, d0 as SharedToolOptions, d1 as TopologyConflict, d2 as TopologyStore, d3 as TransmissionEventDirection, d4 as TransmissionEventOptions, d5 as TransmissionId, d6 as TransmissionOptions, d7 as TransmissionPredicateOptions, d8 as TransmissionSerializationContext, d9 as UpdateAgentInstanceOptions, da as UpdateConversationOptions, db as WaitOptions, dc as compileApplicationManifest, dd as composeAgent, de as composePlaybook, df as configureLayer, dg as configureMemory, dh as createAgentInstance, di as createConversation, dj as createFoundryApproval, dk as createFoundryClient, dl as createFoundryCoreTools, dm as createInstalledApplicationTransmissionTools, dn as createManifest, dp as defineAgent, dq as defineAgentApplication, dr as defineAgentFromModule, ds as defineAgentInstance, dt as defineApp, du as defineApplication, dv as defineCall, dw as defineConnection, dx as defineFacts, dy as defineForms, dz as defineGoals, dA as defineLayer, dB as defineMcp, dC as defineMemory, dD as definePlaybookAction, dE as definePlaybookSubscription, dF as defineRepl, dG as defineRoutes, dH as defineSchedule, dI as defineSharedTool, dJ as defineSubagent, dK as defineSubscriber, dL as defineTransmission, dM as defineTransmissionEvent, dN as defineTransmissionPredicate, dO as defineWorkingEnvironment, dP as discoverAgents, dQ as findAgentFiles, dR as foundryDataEnvironmentPersistence, dS as foundryGuidanceSubject, dT as grantResolverLive, dU as install, dV as installRegistry, dW as installationKey, dX as installedApplicationTransmissionToolName, dY as internalAgentName, dZ as isFoundryAgent, d_ as isFoundryAgentDefinition, d$ as isFoundryApplication, e0 as isFoundryCapability, e1 as isFoundryLayer, e2 as isFoundrySchedule, e3 as isFoundrySubscriber, e4 as isFoundryTransmission, e5 as isInboxCapableStore, e6 as listFoundryApprovals, e7 as memoryAccountDirectory, e8 as memoryEventStore, e9 as memoryTopologyStore, ea as mountAgentDefinitionMemory, eb as mountFoundrySurfaces, ec as reconstructAgentInstance, ed as reconstructPlaybook, ee as reconstructPlaybookSubscription, ef as resolveFoundryApproval, eg as routeFromAgentFile, eh as routeFromInternalAgentName, ei as toGloveMessage, ej as toGloveRequestInput, ek as transmissionPredicate, el as withFoundryPermissions } from './client-CLTds1uV.js';
|
|
3
3
|
import { Effect } from 'effect';
|
|
4
4
|
import { EnvSnapshot } from 'glove-working-environment';
|
|
5
5
|
import { AddressInfo } from 'node:net';
|
package/dist/index.js
CHANGED
|
@@ -43,12 +43,12 @@ import {
|
|
|
43
43
|
memoryTopologyStore,
|
|
44
44
|
serializeInboundTransmissionXml,
|
|
45
45
|
writeGeneratedTypes
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-D2AHSYOB.js";
|
|
47
47
|
import {
|
|
48
48
|
FoundryClient,
|
|
49
49
|
FoundryRunHandle,
|
|
50
50
|
createFoundryClient
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-7F7QVO6I.js";
|
|
52
52
|
import {
|
|
53
53
|
defineConfig
|
|
54
54
|
} from "./chunk-ZFNMFE3T.js";
|
|
@@ -63,25 +63,22 @@ import {
|
|
|
63
63
|
defineWorkingEnvironment,
|
|
64
64
|
foundryDataEnvironmentPersistence,
|
|
65
65
|
foundryGuidanceSubject
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-NHV64WNO.js";
|
|
67
67
|
import {
|
|
68
68
|
EMPTY_AGENT_COMPOSITION,
|
|
69
69
|
EMPTY_CAPABILITY_REGISTRY,
|
|
70
70
|
EMPTY_FOUNDRY_APPLICATION,
|
|
71
|
-
EMPTY_NATIVE_REGISTRY,
|
|
72
71
|
FOUNDRY_AGENT_APPLICATION_BRAND,
|
|
73
72
|
FOUNDRY_APPLICATION_BRAND,
|
|
74
73
|
FOUNDRY_APPROVAL_DIRECTORY_ENV,
|
|
75
74
|
FOUNDRY_COMPOSED_PLAYBOOK_BRAND,
|
|
76
75
|
FOUNDRY_CONNECTION_BRAND,
|
|
77
76
|
FOUNDRY_CORE_COMMAND_EVENT,
|
|
78
|
-
FOUNDRY_LAYER_BRAND,
|
|
79
77
|
FOUNDRY_MCP_BRAND,
|
|
80
78
|
FOUNDRY_MEMORY_BRAND,
|
|
81
79
|
FOUNDRY_PLAYBOOK_ACTION_BRAND,
|
|
82
80
|
FOUNDRY_SCHEDULE_BRAND,
|
|
83
81
|
FOUNDRY_SHARED_TOOL_BRAND,
|
|
84
|
-
FOUNDRY_SUBSCRIBER_BRAND,
|
|
85
82
|
FOUNDRY_TRANSMISSION_BRAND,
|
|
86
83
|
FOUNDRY_TRANSMISSION_EVENT_BRAND,
|
|
87
84
|
FOUNDRY_TRANSMISSION_PREDICATE_BRAND,
|
|
@@ -89,7 +86,6 @@ import {
|
|
|
89
86
|
MemoryFoundryDataAdapter,
|
|
90
87
|
composeAgent,
|
|
91
88
|
composePlaybook,
|
|
92
|
-
configureLayer,
|
|
93
89
|
configureMemory,
|
|
94
90
|
createAgentInstance,
|
|
95
91
|
createConversation,
|
|
@@ -102,14 +98,12 @@ import {
|
|
|
102
98
|
defineApp,
|
|
103
99
|
defineApplication,
|
|
104
100
|
defineConnection,
|
|
105
|
-
defineLayer,
|
|
106
101
|
defineMcp,
|
|
107
102
|
defineMemory,
|
|
108
103
|
definePlaybookAction,
|
|
109
104
|
definePlaybookSubscription,
|
|
110
105
|
defineSchedule,
|
|
111
106
|
defineSharedTool,
|
|
112
|
-
defineSubscriber,
|
|
113
107
|
defineTransmission,
|
|
114
108
|
defineTransmissionEvent,
|
|
115
109
|
defineTransmissionPredicate,
|
|
@@ -121,14 +115,11 @@ import {
|
|
|
121
115
|
installedApplicationTransmissionToolName,
|
|
122
116
|
isFoundryApplication,
|
|
123
117
|
isFoundryCapability,
|
|
124
|
-
isFoundryLayer,
|
|
125
118
|
isFoundrySchedule,
|
|
126
|
-
isFoundrySubscriber,
|
|
127
119
|
isFoundryTransmission,
|
|
128
120
|
isInboxCapableStore,
|
|
129
121
|
listFoundryApprovals,
|
|
130
122
|
mountAgentDefinitionMemory,
|
|
131
|
-
mountFoundrySurfaces,
|
|
132
123
|
reconstructAgentInstance,
|
|
133
124
|
reconstructPlaybook,
|
|
134
125
|
reconstructPlaybookSubscription,
|
|
@@ -138,8 +129,9 @@ import {
|
|
|
138
129
|
toGloveRequestInput,
|
|
139
130
|
transmissionPredicate,
|
|
140
131
|
withFoundryPermissions
|
|
141
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-6Q2LGPSC.js";
|
|
142
133
|
import {
|
|
134
|
+
EMPTY_NATIVE_REGISTRY,
|
|
143
135
|
FOUNDRY_AGENT_BRAND,
|
|
144
136
|
FOUNDRY_AGENT_DEFINITION_BRAND,
|
|
145
137
|
FOUNDRY_AGENT_FILE_ENV,
|
|
@@ -147,16 +139,24 @@ import {
|
|
|
147
139
|
FOUNDRY_APPLICATION_ENV,
|
|
148
140
|
FOUNDRY_EVENT_PREFIX,
|
|
149
141
|
FOUNDRY_EXECUTION_MARKER,
|
|
142
|
+
FOUNDRY_LAYER_BRAND,
|
|
143
|
+
FOUNDRY_SUBSCRIBER_BRAND,
|
|
144
|
+
configureLayer,
|
|
150
145
|
defineAgent,
|
|
151
146
|
defineAgentFromModule,
|
|
152
147
|
defineCall,
|
|
148
|
+
defineLayer,
|
|
153
149
|
defineRoutes,
|
|
154
150
|
defineSubagent,
|
|
151
|
+
defineSubscriber,
|
|
155
152
|
internalAgentName,
|
|
156
153
|
isFoundryAgent,
|
|
157
154
|
isFoundryAgentDefinition,
|
|
155
|
+
isFoundryLayer,
|
|
156
|
+
isFoundrySubscriber,
|
|
157
|
+
mountFoundrySurfaces,
|
|
158
158
|
routeFromInternalAgentName
|
|
159
|
-
} from "./chunk-
|
|
159
|
+
} from "./chunk-PVOKR4CN.js";
|
|
160
160
|
|
|
161
161
|
// src/file-data.ts
|
|
162
162
|
import { randomUUID } from "node:crypto";
|
|
@@ -38,7 +38,7 @@ Native Glove media parts may include a human-facing `name`. A custom `run` handl
|
|
|
38
38
|
persist or normalize those parts and then call `context.defaultRun(enrichedMessage)`
|
|
39
39
|
to keep the standard Glove loop and conversation semantics.
|
|
40
40
|
|
|
41
|
-
The generated project depends on the
|
|
41
|
+
The generated project depends on caret ranges of the Glove versions the `glove-foundry` that created it was built against (for example `^0.4.2` when it was built with `glove-js@0.4.2`). That is not tidiness: an older range makes the package manager install a second copy of `glove-js`, and the two `JsSession` classes then fail to type-match.
|
|
42
42
|
|
|
43
43
|
### Templates
|
|
44
44
|
|
|
@@ -63,11 +63,13 @@ A directory holding a Next.js app is detected, so `--target` is usually unnecess
|
|
|
63
63
|
| `foundry/agents/**` | The agents |
|
|
64
64
|
| `foundry/foundry.application.ts` | Data adapter, accounts, routes |
|
|
65
65
|
| `foundry/package.json` | `{"type":"module"}`, scoping ESM to the agents |
|
|
66
|
+
| `foundry/lib/**` | The template's helpers, such as the durable transcript store |
|
|
67
|
+
| `foundry/.gitignore` | Ignores `foundry/.data/`, where runtime data, transcripts and memory are written |
|
|
66
68
|
| `foundry.config.mts` | Points the runtime at `foundry/agents` |
|
|
67
69
|
| `lib/foundry.ts` | A typed client your app imports |
|
|
68
70
|
| `app/api/<agent>/route.ts` | An example route handler |
|
|
69
71
|
|
|
70
|
-
Your `package.json` keeps its name, scripts, and dependencies; it gains `foundry:dev
|
|
72
|
+
Your `package.json` keeps its name, scripts, and unrelated dependencies; it gains `foundry:dev` and `foundry:start`. The Glove packages, `effect` and `zod` are set to the ranges this Foundry requires, replacing any version the app already declared (an app on `zod@3` is moved to `zod@4`). Every other file the app owns is left untouched; Foundry's runtime data goes to `foundry/.data/`, ignored by `foundry/.gitignore`.
|
|
71
73
|
|
|
72
74
|
The runtime is a separate process from `next dev`, deliberately — it holds durable state and should not restart when a component changes. The app reaches it over HTTP through `lib/foundry.ts`, so no part of the agent graph is bundled into your app, and `FoundryRoutes` stays a type-only import.
|
|
73
75
|
|
|
@@ -38,7 +38,7 @@ The Glove Foundry and Glove skills guided integration against native primitives
|
|
|
38
38
|
|
|
39
39
|
| Surface | Result |
|
|
40
40
|
| --- | --- |
|
|
41
|
-
| Entire publish build graph | Passed
|
|
41
|
+
| Entire publish build graph | Passed; no publishing command run |
|
|
42
42
|
| Foundry runtime suite | 80 passed, including real completed/cancelled worker process cleanup |
|
|
43
43
|
| New initializer and existing scaffold tests | 11 passed; terminal policy, flags, piped setup, invalid options, Next.js preservation, versions, and all four package-manager dispatch paths |
|
|
44
44
|
| Interactive terminal | Selected minimal starter and npm; confirmed generation; separately cancelled with Ctrl+C and verified no output directory |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "glove-foundry",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "An Effect-native, file-routed framework for typed, observable Glove agent applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -72,15 +72,15 @@
|
|
|
72
72
|
"station-client": "^3.0.0",
|
|
73
73
|
"station-beacon": "^3.0.0",
|
|
74
74
|
"station-broadcast": "^3.0.0",
|
|
75
|
-
"glove-
|
|
76
|
-
"glove-
|
|
77
|
-
"glove-
|
|
78
|
-
"glove-
|
|
79
|
-
"glove-
|
|
80
|
-
"glove-
|
|
81
|
-
"glove-python": "0.4.1",
|
|
75
|
+
"glove-js": "0.5.2",
|
|
76
|
+
"glove-core": "4.3.0",
|
|
77
|
+
"glove-lisp": "0.5.2",
|
|
78
|
+
"glove-memory": "2.2.3",
|
|
79
|
+
"glove-facts": "0.1.4",
|
|
80
|
+
"glove-mcp": "1.2.2",
|
|
82
81
|
"glove-working-environment": "0.7.0",
|
|
83
|
-
"glove-
|
|
82
|
+
"glove-python": "0.4.2",
|
|
83
|
+
"glove-mesh": "0.1.7"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@types/node": "^25.2.3",
|
|
@@ -17,7 +17,9 @@ cp .env.example .env.local # add your OPENROUTER_API_KEY
|
|
|
17
17
|
|
|
18
18
|
Then open **http://127.0.0.1:4141** and press **Start a run**.
|
|
19
19
|
|
|
20
|
-
Choose **assistant**,
|
|
20
|
+
Choose **assistant**, ask "What time is it?", and open the run to inspect its events —
|
|
21
|
+
including the `current_time` tool call. Send a follow-up in the same conversation
|
|
22
|
+
(the **Chat** page is easiest): the assistant remembers the earlier turn.
|
|
21
23
|
Edit `agents/assistant/agent.ts`, save, and run again. The dev server reloads your
|
|
22
24
|
definition. Run `{{typecheckCommand}}` and `{{lintCommand}}` after changes.
|
|
23
25
|
|
|
@@ -26,14 +28,22 @@ yourself and restart the dev server. Do not commit the key. If a run fails, chec
|
|
|
26
28
|
the trace for authentication or rate-limit errors. If port 4141 is occupied, use
|
|
27
29
|
the local `glove foundry dev --port 4142` command.
|
|
28
30
|
|
|
29
|
-
##
|
|
31
|
+
## Where state lives
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
Foundry runs every message in a fresh process, so nothing an agent needs on the
|
|
34
|
+
next message can live only in memory. The starter keeps it on disk under `.data/`
|
|
35
|
+
(git-ignored):
|
|
36
|
+
|
|
37
|
+
| What | Where | Wired in |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| Instances, conversations, schedules, workspace data | `.data/foundry.json` | `foundry.application.ts` (`FileFoundryDataAdapter`) |
|
|
40
|
+
| Conversation transcripts | `.data/transcripts/` | `agents/assistant/agent.ts` (`store`, using `lib/file-store.ts`) |
|
|
41
|
+
|
|
42
|
+
State therefore survives the restart `{{devCommand}}` performs on every save. Delete
|
|
43
|
+
`.data/` to start fresh. Both adapters are single-host: use database-backed
|
|
44
|
+
adapters when several hosts share one runtime. A non-loopback listener requires an
|
|
36
45
|
application-owned `requestAuthorization` adapter and a deliberate network boundary.
|
|
46
|
+
See https://glove.dterminal.net/foundry/docs/persistence.
|
|
37
47
|
|
|
38
48
|
## The one idea to understand first
|
|
39
49
|
|
|
@@ -58,7 +68,23 @@ Any file matching these names under an agent folder is discovered automatically.
|
|
|
58
68
|
| `layers/*.layer.ts` | Native Glove setup | `defineLayer` |
|
|
59
69
|
| `subscribers/*.subscriber.ts` | An observer | `defineSubscriber` |
|
|
60
70
|
|
|
61
|
-
|
|
71
|
+
### Two ways to add a tool
|
|
72
|
+
|
|
73
|
+
- **Every instance has it:** add a tool object to the agent's `tools` array, like
|
|
74
|
+
`current_time` in `agents/assistant/agent.ts`. Save, and the next run has it.
|
|
75
|
+
- **Instances opt in:** create `agents/assistant/tools/<name>.tool.ts` with
|
|
76
|
+
`defineSharedTool`, list it in the agent's `components: composeAgent(...)`, then
|
|
77
|
+
install it on an instance. Composing makes it *available*, not mounted:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
curl -X PUT http://127.0.0.1:4141/api/installations \
|
|
81
|
+
-H 'content-type: application/json' \
|
|
82
|
+
-d '{"agentId":"<instance-id>","kind":"tool","id":"<name>"}'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
You can also install with `install(...)` when creating an instance in code, or
|
|
86
|
+
`client.install(...)`. The inspector shows installations but does not change them.
|
|
87
|
+
Apps and MCP servers work the same way.
|
|
62
88
|
|
|
63
89
|
Schedules are data, not auto-discovered file routes. You may keep a `defineSchedule`
|
|
64
90
|
value in an ordinary colocated module and import it into the agent's lazy
|
|
@@ -1,28 +1,42 @@
|
|
|
1
|
-
import { MemoryStore } from "glove-core";
|
|
2
1
|
import { createAdapter } from "glove-core/models/providers";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
2
|
+
import { defineAgent } from "glove-foundry";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { FileStore } from "../../lib/file-store.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The file path is the identity: this is the agent `assistant`.
|
|
8
8
|
*
|
|
9
9
|
* Every field may be a value or a function; a function is called per run with
|
|
10
|
-
* the request context.
|
|
11
|
-
*
|
|
10
|
+
* the request context. Each run executes in its own process, so state that must
|
|
11
|
+
* outlive one message — like the conversation below — lives on disk.
|
|
12
12
|
*/
|
|
13
13
|
export default defineAgent({
|
|
14
14
|
description: "A general-purpose Glove assistant",
|
|
15
|
-
components: composeAgent(currentTime),
|
|
16
|
-
store: ({ conversationId }) => new MemoryStore(`assistant:${conversationId}`),
|
|
17
15
|
model: () => createAdapter({
|
|
18
16
|
provider: "openrouter",
|
|
19
17
|
model: process.env.OPENROUTER_MODEL ?? "openai/gpt-4.1-mini",
|
|
20
18
|
stream: true,
|
|
21
19
|
}),
|
|
22
|
-
|
|
20
|
+
|
|
21
|
+
// Durable history: without it the assistant forgets the previous message.
|
|
22
|
+
store: ({ conversationId }) => FileStore.open(conversationId),
|
|
23
|
+
|
|
24
|
+
systemPrompt: (_agent, { history }) => [
|
|
23
25
|
"You are a precise, practical assistant.",
|
|
24
|
-
`
|
|
25
|
-
`Prior messages: ${history.length}`,
|
|
26
|
+
`Prior messages in this conversation: ${history.length}.`,
|
|
26
27
|
].join("\n"),
|
|
28
|
+
|
|
29
|
+
// Tools listed here are on every instance of this agent. To make a tool
|
|
30
|
+
// installable per instance instead, put it in tools/<name>.tool.ts with
|
|
31
|
+
// defineSharedTool, add it to composeAgent(...), and install it (see README).
|
|
32
|
+
tools: [{
|
|
33
|
+
name: "current_time",
|
|
34
|
+
description: "Return the current ISO timestamp",
|
|
35
|
+
inputSchema: z.object({}),
|
|
36
|
+
async do() {
|
|
37
|
+
return { status: "success", data: new Date().toISOString() };
|
|
38
|
+
},
|
|
39
|
+
}],
|
|
40
|
+
|
|
27
41
|
compactionInstructions: () => "Preserve decisions, open work, and important context.",
|
|
28
42
|
});
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FileFoundryDataAdapter, defineApplication } from "glove-foundry";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
|
|
3
|
-
/**
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Instances, conversations, schedules and workspace data are saved to
|
|
6
|
+
* `.data/foundry.json`, so they survive restarts — including the restart
|
|
7
|
+
* `dev` performs every time you save a file. Delete `.data/` to start fresh.
|
|
8
|
+
* Use a database-backed adapter when several hosts share one runtime.
|
|
9
|
+
*/
|
|
10
|
+
export const data = new FileFoundryDataAdapter({
|
|
11
|
+
file: fileURLToPath(new URL("./.data/foundry.json", import.meta.url)),
|
|
12
|
+
});
|
|
5
13
|
|
|
6
14
|
export default defineApplication({
|
|
7
15
|
name: "{{projectName}}",
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import {
|
|
6
|
+
MemoryStore,
|
|
7
|
+
type InboxItem,
|
|
8
|
+
type Message,
|
|
9
|
+
type Task,
|
|
10
|
+
type TokenConsumptionCounter,
|
|
11
|
+
} from "glove-core";
|
|
12
|
+
|
|
13
|
+
/** Transcripts live in `.data/transcripts`, beside this project's `lib` folder. */
|
|
14
|
+
const TRANSCRIPTS = fileURLToPath(new URL("../.data/transcripts/", import.meta.url));
|
|
15
|
+
|
|
16
|
+
interface SavedConversation {
|
|
17
|
+
readonly messages: Message[];
|
|
18
|
+
readonly turns: number;
|
|
19
|
+
readonly tokens: TokenConsumptionCounter;
|
|
20
|
+
readonly tasks: Task[];
|
|
21
|
+
readonly inbox: InboxItem[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Foundry runs every message in a fresh process, so a plain `MemoryStore`
|
|
26
|
+
* would start each turn with no history. This one loads the conversation from
|
|
27
|
+
* a JSON file and rewrites it after every change.
|
|
28
|
+
*
|
|
29
|
+
* One host, one active run per conversation. Replace it with a database-backed
|
|
30
|
+
* StoreAdapter when several hosts share conversations.
|
|
31
|
+
*/
|
|
32
|
+
export class FileStore extends MemoryStore {
|
|
33
|
+
private restoring = false;
|
|
34
|
+
|
|
35
|
+
private constructor(conversationId: string, private readonly file: string) {
|
|
36
|
+
super(conversationId);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static async open(conversationId: string, directory = TRANSCRIPTS): Promise<FileStore> {
|
|
40
|
+
const name = createHash("sha256").update(conversationId).digest("hex").slice(0, 32);
|
|
41
|
+
const store = new FileStore(conversationId, join(directory, `${name}.json`));
|
|
42
|
+
await store.restore();
|
|
43
|
+
return store;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private async restore(): Promise<void> {
|
|
47
|
+
let saved: SavedConversation;
|
|
48
|
+
try {
|
|
49
|
+
saved = JSON.parse(await readFile(this.file, "utf8")) as SavedConversation;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") return;
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
this.restoring = true;
|
|
55
|
+
try {
|
|
56
|
+
await this.appendMessages(saved.messages);
|
|
57
|
+
await this.addTokens(saved.tokens);
|
|
58
|
+
for (let turn = 0; turn < saved.turns; turn++) await this.incrementTurn();
|
|
59
|
+
await this.addTasks(saved.tasks);
|
|
60
|
+
for (const item of saved.inbox) await this.addInboxItem(item);
|
|
61
|
+
} finally {
|
|
62
|
+
this.restoring = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private async save(): Promise<void> {
|
|
67
|
+
if (this.restoring) return;
|
|
68
|
+
const saved: SavedConversation = {
|
|
69
|
+
messages: await this.getMessages(),
|
|
70
|
+
turns: await this.getTurnCount(),
|
|
71
|
+
tokens: await this.getTokenConsumption(),
|
|
72
|
+
tasks: await this.getTasks(),
|
|
73
|
+
inbox: await this.getInboxItems(),
|
|
74
|
+
};
|
|
75
|
+
await mkdir(dirname(this.file), { recursive: true });
|
|
76
|
+
const temporary = `${this.file}.${process.pid}.tmp`;
|
|
77
|
+
await writeFile(temporary, JSON.stringify(saved));
|
|
78
|
+
await rename(temporary, this.file);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
override async appendMessages(messages: Message[]) { await super.appendMessages(messages); await this.save(); }
|
|
82
|
+
override async addTokens(usage: TokenConsumptionCounter) { await super.addTokens(usage); await this.save(); }
|
|
83
|
+
override async incrementTurn() { await super.incrementTurn(); await this.save(); }
|
|
84
|
+
override async resetCounters() { await super.resetCounters(); await this.save(); }
|
|
85
|
+
override async addTasks(tasks: Task[]) { await super.addTasks(tasks); await this.save(); }
|
|
86
|
+
override async updateTask(id: string, updates: Partial<Pick<Task, "status" | "content" | "activeForm">>) {
|
|
87
|
+
await super.updateTask(id, updates);
|
|
88
|
+
await this.save();
|
|
89
|
+
}
|
|
90
|
+
override async addInboxItem(item: InboxItem) { await super.addInboxItem(item); await this.save(); }
|
|
91
|
+
override async updateInboxItem(id: string, updates: Partial<Pick<InboxItem, "status" | "response" | "resolved_at">>) {
|
|
92
|
+
await super.updateInboxItem(id, updates);
|
|
93
|
+
await this.save();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -19,9 +19,15 @@ cp .env.example .env.local # optional: add OPENROUTER_API_KEY for real answe
|
|
|
19
19
|
Then open **http://127.0.0.1:4141** and press **Start a run**.
|
|
20
20
|
|
|
21
21
|
Choose **concierge** and send “Find a flight to Nairobi.” Open the resulting run
|
|
22
|
-
to follow its model calls, tool
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
to follow its model calls, the `find_flights` tool call and the result. Send a
|
|
23
|
+
follow-up in the same conversation (the **Chat** page is easiest): the concierge
|
|
24
|
+
remembers the earlier turn. This is a deterministic demo: flights, calendar and
|
|
25
|
+
messaging are examples, not live provider integrations. Change
|
|
26
|
+
`agents/concierge/agent.ts`, save, and try another run to see the reload.
|
|
27
|
+
|
|
28
|
+
The run drawer creates a new instance by default. Pick **concierge-demo** instead
|
|
29
|
+
to use the seeded instance that has the calendar app and currency tool installed
|
|
30
|
+
and may reply over chat — see [Send it a chat message](#send-it-a-chat-message).
|
|
25
31
|
|
|
26
32
|
To get live model answers, put your own `OPENROUTER_API_KEY` in `.env.local`, then
|
|
27
33
|
restart the dev server. Never commit that file. The wizard does not collect keys.
|
|
@@ -33,7 +39,7 @@ Setting a model key does not connect a real calendar or messenger by itself.
|
|
|
33
39
|
- Run `{{installCommand}}` again if installation was interrupted; project files are retained.
|
|
34
40
|
- If port 4141 is occupied, run the local `glove foundry dev --port 4142` command and open that address.
|
|
35
41
|
- If a run fails, open its event trace; a provider rate limit is different from a typecheck failure.
|
|
36
|
-
-
|
|
42
|
+
- State lives in `.data/` and survives restarts. Delete `.data/` to start fresh (for example after renaming an installed tool). Read **Going to production** before storing real user work.
|
|
37
43
|
|
|
38
44
|
---
|
|
39
45
|
|
|
@@ -57,23 +63,28 @@ One definition serves many instances. Two travellers can run the same concierge
|
|
|
57
63
|
```
|
|
58
64
|
agents/concierge/
|
|
59
65
|
agent.ts the agent. start here
|
|
60
|
-
composition.ts composeAgent(...) —
|
|
61
|
-
|
|
66
|
+
composition.ts composeAgent(...) — the installable catalogue
|
|
67
|
+
flights.ts find_flights: always on, every instance
|
|
68
|
+
tools/convert-currency.tool.ts a shared tool an instance installs
|
|
62
69
|
apps/calendar.app.ts an application an instance installs
|
|
70
|
+
instances.ts the seeded concierge-demo instance + its binding
|
|
63
71
|
transmissions/messaging.transmission.ts Telegram/WhatsApp-shaped transport
|
|
64
72
|
events/message-received.event.ts an inbound event
|
|
65
73
|
events/message-sent.event.ts an outbound event
|
|
66
74
|
predicates/mentions-trip.predicate.ts routing logic, kept out of the agent
|
|
67
|
-
memory/traveller.memory.ts ambient context
|
|
75
|
+
memory/traveller.memory.ts ambient context, saved per instance
|
|
68
76
|
schedules/trip-countdown.ts recurring work
|
|
69
77
|
layers/trip-context.layer.ts direct access to the native Glove runtime
|
|
70
78
|
subscribers/usage.subscriber.ts observation without behaviour change
|
|
71
|
-
workbench.ts the agent's VFS + JavaScript REPL
|
|
79
|
+
workbench.ts the agent's VFS (persisted) + JavaScript REPL
|
|
72
80
|
topology.ts accounts and routes (runtime data)
|
|
73
81
|
|
|
74
|
-
foundry.application.ts data adapter, accounts, routes
|
|
82
|
+
foundry.application.ts data adapter, accounts, routes, bindings
|
|
75
83
|
foundry.config.ts port, execution policy
|
|
76
84
|
lib/demo-model.ts keyless model — delete once you have a key
|
|
85
|
+
lib/file-store.ts durable conversation transcripts
|
|
86
|
+
lib/file-context.ts durable traveller memory
|
|
87
|
+
.data/ runtime state (git-ignored). delete to reset
|
|
77
88
|
src/client.ts a typed client for these agents
|
|
78
89
|
.foundry/routes.d.ts generated. do not edit
|
|
79
90
|
```
|
|
@@ -105,7 +116,10 @@ Assembly fields such as tools, memory, and schedules accept **a value or a funct
|
|
|
105
116
|
|
|
106
117
|
### Add a tool
|
|
107
118
|
|
|
108
|
-
|
|
119
|
+
Two ways, depending on who should have it:
|
|
120
|
+
|
|
121
|
+
- **Every instance:** export a plain tool object and add it to the agent's `tools` field, like `find_flights` in `flights.ts`.
|
|
122
|
+
- **Instances that opt in:** create `agents/concierge/tools/weather.tool.ts`, default-export `defineSharedTool({...})`, add it to `composition.ts`, and install it on an instance (below), like `convert-currency`. Composing makes it available; installing mounts it.
|
|
109
123
|
|
|
110
124
|
### Add a second agent
|
|
111
125
|
|
|
@@ -113,7 +127,7 @@ Create `agents/<name>/agent.ts`. It is immediately routable, appears in the insp
|
|
|
113
127
|
|
|
114
128
|
### Give an instance a capability
|
|
115
129
|
|
|
116
|
-
|
|
130
|
+
Shared tools, applications and MCP servers stay inert until an instance installs them. `instances.ts` seeds `concierge-demo` with `convert-currency` and `calendar` installed. To install on another instance, use the API (the inspector shows installations but does not change them):
|
|
117
131
|
|
|
118
132
|
```bash
|
|
119
133
|
curl -X PUT http://127.0.0.1:4141/api/installations \
|
|
@@ -121,6 +135,26 @@ curl -X PUT http://127.0.0.1:4141/api/installations \
|
|
|
121
135
|
-d '{"agentId":"<instance-id>","kind":"application","id":"calendar","config":{"calendarId":"primary"}}'
|
|
122
136
|
```
|
|
123
137
|
|
|
138
|
+
### Send it a chat message
|
|
139
|
+
|
|
140
|
+
The calendar app owns the messaging transmission, and `concierge-demo` has both the
|
|
141
|
+
app installed and a **binding** (in `instances.ts`) that lets it reply on the
|
|
142
|
+
outbound route. Its `traveller-chat` playbook is written onto the instance during
|
|
143
|
+
its first run, so send it one message first (Chat page, or **Start a run** with
|
|
144
|
+
`concierge-demo` selected). Then deliver an inbound chat message:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
curl -X POST http://127.0.0.1:4141/api/transmissions/traveller-inbound/fire \
|
|
148
|
+
-H 'content-type: application/json' \
|
|
149
|
+
-d '{"eventId":"evt-1","threadKey":"thread-42","raw":{"threadId":"thread-42","text":"Any flight to Nairobi in April?"}}'
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The message mentions a flight, so the playbook matches and starts a run. The agent
|
|
153
|
+
searches flights and replies through the generated `glove_app_calendar__messaging_send`
|
|
154
|
+
tool; the demo transport prints `[telegram] -> thread-42: …` in the terminal running
|
|
155
|
+
`{{devCommand}}`. An instance without the binding cannot send: delivery fails with
|
|
156
|
+
"agent has no enabled bindings".
|
|
157
|
+
|
|
124
158
|
### Connect a real chat app
|
|
125
159
|
|
|
126
160
|
`transmissions/messaging.transmission.ts` has the shape; only `deliver` needs a real call.
|
|
@@ -190,7 +224,7 @@ Filters live in the URL, so `/runs?status=failed` is a link you can send. Press
|
|
|
190
224
|
|
|
191
225
|
## Going to production
|
|
192
226
|
|
|
193
|
-
1. **
|
|
227
|
+
1. **Choose where state lives.** Each run executes in its own process, so everything the next message needs is on disk under `.data/`: runtime data (`FileFoundryDataAdapter`), transcripts (`lib/file-store.ts`), traveller memory (`lib/file-context.ts`) and the VFS (`foundryDataEnvironmentPersistence`). These are single-host. For several hosts, replace each with a database-backed adapter — persisting one does not persist the others. See [Persistence](https://glove.dterminal.net/foundry/docs/persistence).
|
|
194
228
|
2. **Delete `lib/demo-model.ts`** and the fallback in `agent.ts` once `OPENROUTER_API_KEY` is set.
|
|
195
229
|
3. **Own your credentials.** Foundry stores account *references*, never secrets. Keep tokens in your own adapter or secret manager.
|
|
196
230
|
4. **Run `{{startCommand}}`** rather than `dev` — no file watching, no restart-on-change.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { MemoryStore } from "glove-core";
|
|
2
1
|
import { createAdapter } from "glove-core/models/providers";
|
|
3
2
|
import { composePlaybook, defineAgent } from "glove-foundry";
|
|
4
3
|
import { DemoModel } from "../../lib/demo-model.js";
|
|
4
|
+
import { FileStore } from "../../lib/file-store.js";
|
|
5
5
|
import reply from "./actions/reply.action.js";
|
|
6
6
|
import calendar from "./apps/calendar.app.js";
|
|
7
7
|
import { conciergeComponents } from "./composition.js";
|
|
8
8
|
import messageReceived from "./events/message-received.event.js";
|
|
9
9
|
import messageSent from "./events/message-sent.event.js";
|
|
10
|
+
import { findFlights } from "./flights.js";
|
|
10
11
|
import tripContext from "./layers/trip-context.layer.js";
|
|
11
12
|
import travellerMemory from "./memory/traveller.memory.js";
|
|
12
13
|
import mentionsTrip from "./predicates/mentions-trip.predicate.js";
|
|
@@ -67,15 +68,20 @@ export default defineAgent({
|
|
|
67
68
|
tags: ["travel", "example"],
|
|
68
69
|
components: conciergeComponents,
|
|
69
70
|
|
|
70
|
-
//
|
|
71
|
+
// Each run executes in its own process, so anything that must outlive one
|
|
72
|
+
// message lives on disk: the transcript here, traveller memory in memory/.
|
|
71
73
|
memory: [travellerMemory],
|
|
72
|
-
store: ({ conversationId }) =>
|
|
74
|
+
store: ({ conversationId }) => FileStore.open(conversationId),
|
|
73
75
|
model,
|
|
74
76
|
|
|
77
|
+
// Always on: every instance can search flights. Installable capabilities
|
|
78
|
+
// (calendar, convert-currency) mount only where an instance installed them.
|
|
79
|
+
tools: [findFlights],
|
|
80
|
+
|
|
75
81
|
// The prompt is built per run, so it can name what is actually mounted.
|
|
76
82
|
systemPrompt: (_agent, { message, history, installations }) => [
|
|
77
83
|
"You are a travel concierge. You are practical and you never invent bookings.",
|
|
78
|
-
"Use find_flights for availability, and the calendar tools before proposing dates.",
|
|
84
|
+
"Use find_flights for availability, and the calendar tools (when installed) before proposing dates.",
|
|
79
85
|
`Traveller asked: ${message.text}`,
|
|
80
86
|
`Prior messages: ${history.length}.`,
|
|
81
87
|
`Installed for this instance: ${installations.map((item) => `${item.kind}:${item.id}`).join(", ") || "nothing yet"}.`,
|