Skip to content

Commit 5de2d08

Browse files
committed
feat(agent-playground): integrate scoped client for project-specific data handling
feat(multi-project): enhance template seeder with namespace datasets and flush persistence
1 parent b41428c commit 5de2d08

2 files changed

Lines changed: 22 additions & 3 deletions

File tree

apps/studio/src/plugins/built-in/agent-playground-plugin.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
1414
import { defineStudioPlugin } from '@objectstack/spec/studio';
1515
import { useClient } from '@objectstack/client-react';
16+
import { useParams } from '@tanstack/react-router';
17+
import { useScopedClient } from '@/hooks/useObjectStackClient';
1618
import { useChat } from '@ai-sdk/react';
1719
import { DefaultChatTransport } from 'ai';
1820
import type { UIMessage } from 'ai';
@@ -305,7 +307,10 @@ function ToolInvocationDisplay({ part, onApprove, onDeny }: ToolInvocationDispla
305307
* Agent Playground Viewer Component
306308
*/
307309
function AgentPlaygroundViewer({ metadataType, metadataName, data, packageId }: MetadataViewerProps) {
308-
const client = useClient();
310+
const unscopedClient = useClient();
311+
const params = useParams({ strict: false }) as { projectId?: string };
312+
const scopedClient = useScopedClient(params.projectId);
313+
const client: any = scopedClient ?? unscopedClient;
309314
const [agent, setAgent] = useState<Agent | null>(data ?? null);
310315
const [loading, setLoading] = useState(!data);
311316
const [input, setInput] = useState('');

packages/runtime/src/multi-project-plugin.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import type { Contracts } from '@objectstack/spec';
2626
import { Plugin, PluginContext } from '@objectstack/core';
27+
import { SeedLoaderConfigSchema } from '@objectstack/spec/data';
2728
import {
2829
DefaultEnvironmentDriverRegistry,
2930
type EnvironmentDriverRegistry,
@@ -159,7 +160,7 @@ function createTemplateSeeder(
159160

160161
const bundle = await template.load();
161162
const items = bundle ? extractMetadataItems(bundle) : [];
162-
const dataSets = Array.isArray(bundle?.data) ? bundle.data : [];
163+
const dataSets = bundle ? namespaceDatasets(bundle) : [];
163164

164165
// Empty bundle (e.g. the "blank" template) → nothing to seed.
165166
if (items.length === 0 && dataSets.length === 0) return;
@@ -206,7 +207,20 @@ function createTemplateSeeder(
206207

207208
if (dataSets.length > 0) {
208209
const seedLoader = new SeedLoaderService(engine, metadata, console as any);
209-
await seedLoader.load({ datasets: dataSets, config: {} as any });
210+
const config = SeedLoaderConfigSchema.parse({});
211+
await seedLoader.load({ datasets: dataSets, config });
212+
}
213+
214+
// Force a persistence flush so the per-project JSON file is
215+
// written before the provisioning handler returns; otherwise
216+
// the memory driver's dirty flag only saves on a 2s timer and
217+
// early HTTP responses may see an empty file on disk.
218+
const driverWithFlush = (kernel as any).services?.driver ?? (kernel as any).getService?.('driver');
219+
const flushable = typeof driverWithFlush?.flush === 'function'
220+
? driverWithFlush
221+
: null;
222+
if (flushable) {
223+
try { await flushable.flush(); } catch { /* best effort */ }
210224
}
211225
},
212226
};

0 commit comments

Comments
 (0)