React Hooks
The SDK provides 30+ React hooks built on TanStack Query v5 for data fetching, caching, and mutations.
Hook Patterns
All hooks follow consistent patterns:
// Query hooks return data + loading states
const { data, isLoading, error, refetch } = useResource();
// Hooks with actions return both queries and mutations
const { resource, actions } = useResource();
const { create, update, delete: remove } = actions;
// Actions are useMutation wrappers
await create.mutateAsync(data);
Core Hooks
useProjects
import { useProjects } from "@dgidgi-one/sdk";
function ProjectList() {
const {
projects, // UseQueryResult<PaginatedResponse<Project>>
actions: {
create, // UseMutationResult
delete: remove, // UseMutationResult
},
} = useProjects(workspaceId?, options?);
// Query state
const { data, isLoading, error, refetch } = projects;
// Create project
await create.mutateAsync({
name: "My Project",
description: "Description",
language: "TypeScript",
});
// Delete project
await remove.mutateAsync(projectId);
}
useProject
import { useProject } from "@dgidgi-one/sdk";
function ProjectDetail({ id }) {
const {
project, // UseQueryResult<Project>
actions: {
update, // UseMutationResult
},
} = useProject(id);
// Update project
await update.mutateAsync({
name: "Updated Name",
status: "active",
});
}
useProjectVersions
import { useProjectVersions, useProjectVersion } from "@dgidgi-one/sdk";
function VersionList({ projectId }) {
const {
versions, // UseQueryResult<ProjectVersion[]>
actions: {
create, // Create new version
release, // Release a version
setCurrent, // Set as current version
},
} = useProjectVersions(projectId);
// Create new version
const newVersion = await create.mutateAsync({
version: "1.0.0",
releaseNotes: "Initial release",
});
// Release version
await release.mutateAsync(versionId);
// Set as current
await setCurrent.mutateAsync(versionId);
}
function VersionDetail({ projectId, versionId }) {
const {
version, // UseQueryResult<ProjectVersion>
documents, // UseQueryResult<ProjectDocument[]>
actions: {
update,
linkBlueprint,
},
} = useProjectVersion(projectId, versionId);
// Link blueprint to version
await linkBlueprint.mutateAsync({
blueprintId: "blueprint-123",
});
}
useChat
import { useChat } from "@dgidgi-one/sdk";
function Chat() {
const {
sessions, // UseQueryResult<ChatSession[]>
actions: {
start, // Start new session
delete: remove, // Delete session
stop, // Stop running session
refinePrompt, // AI prompt refinement
complete, // Get completions
},
} = useChat({ projectId });
// Start new chat
const session = await start.mutateAsync({
projectId: "project-123",
initialMessage: "Hello!",
});
// Delete session
await remove.mutateAsync(sessionId);
}
useChatSession
import { useChatSession } from "@dgidgi-one/sdk";
function ChatSession({ sessionId }) {
const {
session, // UseQueryResult<ChatSession>
messages, // UseQueryResult<ChatMessage[]>
actions: {
send, // Send message
delete: remove, // Delete message
stop, // Stop generation
},
} = useChatSession(sessionId);
// Send message
await send.mutateAsync({
content: "How do I implement auth?",
role: "user",
});
}
useAgents
import { useAgents, useAgent } from "@dgidgi-one/sdk";
function AgentList() {
const { agents } = useAgents();
return agents.data?.data.map(agent => (
<AgentCard key={agent.id} agent={agent} />
));
}
function AgentDetail({ id }) {
const {
agent,
actions: { update, delete: remove },
} = useAgent(id);
await update.mutateAsync({
name: "Updated Agent",
config: { autonomyLevel: "high" },
});
}
useTenants
import { useTenants, useTenant, useTenantBySlug } from "@dgidgi-one/sdk";
// List all tenants (admin)
const { tenants } = useTenants();
// Get current tenant
const tenant = useTenant();
// Get tenant by slug
const { tenant } = useTenantBySlug("my-org");
useWorkspaces
import { useWorkspaces, useWorkspace, useCreateWorkspace } from "@dgidgi-one/sdk";
function Workspaces() {
const { workspaces, actions: { create } } = useWorkspaces();
const createWorkspace = useCreateWorkspace();
// Create workspace
await create.mutateAsync({
name: "New Workspace",
description: "Team workspace",
});
}
function WorkspaceDetail({ id }) {
const { workspace, actions: { update } } = useWorkspace(id);
}
useConnectors
import { useTenantConnectors, useProjectConnectors } from "@dgidgi-one/sdk";
// Tenant-level connectors (organization)
function ConnectorList() {
const {
connectors, // UseQueryResult<TenantConnector[]>
actions: {
create, // Connect new service
update, // Update connector
delete: remove, // Disconnect
verify, // Verify connection
},
} = useTenantConnectors();
// Connect a new service
await create.mutateAsync({
providerId: "github",
providerName: "GitHub",
category: "source_control",
authType: "oauth",
credentials: { access_token: "..." },
});
// Verify connector
await verify.mutateAsync(connectorId);
// Disconnect
await remove.mutateAsync(connectorId);
}
// Project-level connectors
function ProjectConnectors({ projectId }) {
const {
connectors, // Connectors enabled for this project
actions: {
enable, // Enable connector for project
disable, // Disable connector
update, // Update project config
},
} = useProjectConnectors(projectId);
// Enable a tenant connector for this project
await enable.mutateAsync({
tenantConnectorId: "conn_123",
config: { branch: "main" },
});
}
useConnectorProviders
import { useConnectorProviders } from "@dgidgi-one/sdk";
function ProviderCatalog() {
const {
providers, // All available connector providers
categories, // Provider categories
isLoading,
error,
} = useConnectorProviders();
return providers.map(provider => (
<ProviderCard
key={provider.id}
name={provider.name}
description={provider.description}
authType={provider.authType}
iconName={provider.iconName}
/>
));
}
Streaming Hooks
useStreamingChat
For real-time chat streaming:
import { useStreamingChat } from "@dgidgi-one/sdk";
function StreamingChat() {
const {
isStreaming,
currentText, // Accumulated response text
tasks, // Current tasks/actions
checkpoints, // Execution checkpoints
oodaPhases, // Agent OODA phases
runInfo, // Run metadata
error,
streamMessage, // Start streaming
cancelStream, // Cancel current stream
resetStream, // Reset state
} = useStreamingChat();
const handleSend = async (content: string) => {
await streamMessage({
sessionId: "session-123",
content,
projectId: "project-456",
});
};
return (
<div>
{isStreaming && <Spinner />}
<div>{currentText}</div>
<button onClick={() => handleSend("Hello!")}>Send</button>
{isStreaming && <button onClick={cancelStream}>Cancel</button>}
</div>
);
}
useStructuredStreaming
For structured event streaming:
import { useStructuredStreaming } from "@dgidgi-one/sdk";
function AgentRun() {
const {
isStreaming,
events, // All events received
currentPhase, // Current execution phase
taskCards, // Rendered task cards
stats, // Token/cost stats
error,
startStream,
stopStream,
} = useStructuredStreaming();
await startStream({
endpoint: `/runs/${runId}/stream`,
onEvent: (event) => {
console.log("Event:", event.type, event.data);
},
});
}
Query Options
All hooks accept React Query options:
const { projects } = useProjects(workspaceId, {
enabled: !!workspaceId, // Only fetch when workspaceId exists
staleTime: 5 * 60 * 1000, // 5 minutes
refetchOnWindowFocus: true,
refetchInterval: 30000, // Poll every 30s
onSuccess: (data) => {
console.log("Loaded projects:", data);
},
onError: (error) => {
console.error("Failed to load:", error);
},
});
Cache Invalidation
Mutations automatically invalidate relevant queries:
// When you create a project, the projects list is automatically refetched
await create.mutateAsync({ name: "New Project" });
// projects query is invalidated -> refetches automatically
// Manual invalidation
import { useQueryClient } from "@tanstack/react-query";
const queryClient = useQueryClient();
queryClient.invalidateQueries({ queryKey: ["projects"] });
Query Keys
Standard query key format:
["resource"] // List
["resource", id] // Single item
["resource", id, "nested"] // Nested resource
["resource", { filters }] // Filtered list
// Examples
["projects"]
["projects", "proj-123"]
["projects", "proj-123", "files"]
["chat-sessions", { projectId: "proj-123" }]
Complete Hook Reference
| Hook | Purpose |
|---|---|
useProjects | Project CRUD |
useProject | Single project |
useProjectVersions | Project version management |
useProjectVersion | Single version with documents |
useChat | Chat sessions |
useChatSession | Single chat session |
useAgents | Agent listing |
useAgent | Single agent |
useTenant | Current tenant |
useTenants | Tenant listing |
useTenantBySlug | Tenant by slug |
useWorkspaces | Workspace listing |
useWorkspace | Single workspace |
useDeployments | Deployment listing |
useDeployment | Single deployment |
useTenantConnectors | Organization connectors |
useProjectConnectors | Project-level connectors |
useConnectorProviders | Available connector providers |
useStreamingChat | Real-time chat |
useStructuredStreaming | Event streaming |
useAIGenerate | AI generation |
useAIChat | AI chat completion |
useMarketplace | Marketplace items |
useMCPServers | MCP server listing |
| ... | 10+ more hooks |
Best Practices
- Use hooks, not direct resources - Hooks handle caching and invalidation
- Enable conditionally - Use
enabledoption to prevent unnecessary fetches - Handle loading states - Always check
isLoadingbefore rendering data - Handle errors gracefully - Use
errorstate or error boundaries - Use optimistic updates - For better UX on mutations