@objectstack/service-ai 7.2.0 → 7.3.0

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/dist/index.cjs CHANGED
@@ -201,6 +201,7 @@ var init_data_tools = __esm({
201
201
  DEFAULT_QUERY_LIMIT = 20;
202
202
  QUERY_RECORDS_TOOL = {
203
203
  name: "query_records",
204
+ label: "Query Records",
204
205
  description: "Query records from a data object with optional filters, field selection, sorting, and pagination. Returns an array of matching records.",
205
206
  parameters: {
206
207
  type: "object",
@@ -246,6 +247,7 @@ var init_data_tools = __esm({
246
247
  };
247
248
  GET_RECORD_TOOL = {
248
249
  name: "get_record",
250
+ label: "Get Record",
249
251
  description: "Get a single record by its ID from a data object.",
250
252
  parameters: {
251
253
  type: "object",
@@ -270,6 +272,7 @@ var init_data_tools = __esm({
270
272
  };
271
273
  AGGREGATE_DATA_TOOL = {
272
274
  name: "aggregate_data",
275
+ label: "Aggregate Data",
273
276
  description: "Perform aggregation/statistical operations on a data object. Supports count, sum, avg, min, max with optional groupBy and where filters.",
274
277
  parameters: {
275
278
  type: "object",
@@ -2379,6 +2382,7 @@ function cryptoRandomId() {
2379
2382
  }
2380
2383
 
2381
2384
  // src/plugin.ts
2385
+ var import_types = require("@objectstack/types");
2382
2386
  var import_contracts = require("@objectstack/spec/contracts");
2383
2387
 
2384
2388
  // src/stream/vercel-stream-encoder.ts
@@ -5268,6 +5272,7 @@ var QueryPlanSchema = import_zod2.z.object({
5268
5272
  });
5269
5273
  var QUERY_DATA_TOOL = {
5270
5274
  name: "query_data",
5275
+ label: "Query Data (Natural Language)",
5271
5276
  description: "Answer a natural-language question about the user's data. Internally retrieves the relevant object schema, generates an ObjectQL query, executes it, and returns the matching records. Prefer this tool over `query_records` / `aggregate_data` when the user's intent is expressed in plain language.",
5272
5277
  parameters: {
5273
5278
  type: "object",
@@ -5787,6 +5792,82 @@ async function registerActionsAsTools(registry, context) {
5787
5792
 
5788
5793
  // src/agent-runtime.ts
5789
5794
  var import_ai7 = require("@objectstack/spec/ai");
5795
+
5796
+ // src/agents/data-chat-agent.ts
5797
+ var DEFAULT_DATA_AGENT_NAME = "data_chat";
5798
+ var DATA_CHAT_AGENT = {
5799
+ name: DEFAULT_DATA_AGENT_NAME,
5800
+ label: "Data Assistant",
5801
+ role: "Business Data Analyst",
5802
+ instructions: `You are a helpful data assistant that helps users explore and understand their business data through natural language.
5803
+
5804
+ Always answer in the same language the user is using. Detailed tool-usage guidance is supplied by the skills attached to this agent.`,
5805
+ model: {
5806
+ provider: "openai",
5807
+ model: "gpt-4",
5808
+ temperature: 0.3,
5809
+ maxTokens: 4096
5810
+ },
5811
+ // Capability bundle lives on the skill; the agent only references it.
5812
+ // `data_explorer` = read side, `actions_executor` = write side.
5813
+ skills: ["data_explorer", "actions_executor"],
5814
+ active: true,
5815
+ visibility: "global",
5816
+ guardrails: {
5817
+ maxTokensPerInvocation: 8192,
5818
+ maxExecutionTimeSec: 30,
5819
+ blockedTopics: ["delete_records", "drop_table", "alter_schema"]
5820
+ },
5821
+ planning: {
5822
+ strategy: "react",
5823
+ maxIterations: 5,
5824
+ allowReplan: false
5825
+ },
5826
+ memory: {
5827
+ shortTerm: {
5828
+ maxMessages: 20,
5829
+ maxTokens: 4096
5830
+ }
5831
+ }
5832
+ };
5833
+
5834
+ // src/agents/metadata-assistant-agent.ts
5835
+ var METADATA_ASSISTANT_AGENT = {
5836
+ name: "metadata_assistant",
5837
+ label: "Metadata Assistant",
5838
+ role: "Schema Architect",
5839
+ instructions: `You are an expert metadata architect that helps users design and manage their data models through natural language.
5840
+
5841
+ Always answer in the same language the user is using. If the user's request is ambiguous, ask clarifying questions before proceeding. Detailed tool-usage guidance is supplied by the skills attached to this agent.`,
5842
+ model: {
5843
+ provider: "openai",
5844
+ model: "gpt-4",
5845
+ temperature: 0.2,
5846
+ maxTokens: 4096
5847
+ },
5848
+ // Capability bundle lives on the skill; the agent only references it.
5849
+ skills: ["metadata_authoring"],
5850
+ active: true,
5851
+ visibility: "global",
5852
+ guardrails: {
5853
+ maxTokensPerInvocation: 8192,
5854
+ maxExecutionTimeSec: 60,
5855
+ blockedTopics: ["drop_database", "raw_sql", "system_tables"]
5856
+ },
5857
+ planning: {
5858
+ strategy: "react",
5859
+ maxIterations: 10,
5860
+ allowReplan: true
5861
+ },
5862
+ memory: {
5863
+ shortTerm: {
5864
+ maxMessages: 30,
5865
+ maxTokens: 8192
5866
+ }
5867
+ }
5868
+ };
5869
+
5870
+ // src/agent-runtime.ts
5790
5871
  var AgentRuntime = class {
5791
5872
  constructor(metadataService, skillRegistry) {
5792
5873
  this.metadataService = metadataService;
@@ -5937,9 +6018,14 @@ var AgentRuntime = class {
5937
6018
  * chat endpoint when the client doesn't specify an `agentName`.
5938
6019
  *
5939
6020
  * Resolution order:
5940
- * 1. The `defaultAgent` of the app named by `context.appName`.
5941
- * 2. The first active agent in the registry (deterministic fallback).
5942
- * 3. `undefined` if no agents are registered.
6021
+ * 1. The `defaultAgent` of the app named by `context.appName`
6022
+ * (e.g. Studio `metadata_assistant`).
6023
+ * 2. The platform data-query agent (`data_chat`) the implicit
6024
+ * copilot bound to every app that doesn't pin its own. This is
6025
+ * what end users get by default, so they never have to choose.
6026
+ * 3. The first active agent in the registry (last-resort fallback,
6027
+ * e.g. in stripped-down deployments without the data agent).
6028
+ * 4. `undefined` if no agents are registered.
5943
6029
  */
5944
6030
  async resolveDefaultAgent(context) {
5945
6031
  if (context?.appName) {
@@ -5950,6 +6036,8 @@ var AgentRuntime = class {
5950
6036
  if (agent && agent.active !== false) return agent;
5951
6037
  }
5952
6038
  }
6039
+ const dataAgent = await this.loadAgent(DEFAULT_DATA_AGENT_NAME);
6040
+ if (dataAgent && dataAgent.active !== false) return dataAgent;
5953
6041
  const summaries = await this.listAgents();
5954
6042
  if (summaries.length === 0) return void 0;
5955
6043
  return this.loadAgent(summaries[0].name);
@@ -6145,79 +6233,6 @@ var SkillRegistry = class {
6145
6233
  }
6146
6234
  };
6147
6235
 
6148
- // src/agents/data-chat-agent.ts
6149
- var DATA_CHAT_AGENT = {
6150
- name: "data_chat",
6151
- label: "Data Assistant",
6152
- role: "Business Data Analyst",
6153
- instructions: `You are a helpful data assistant that helps users explore and understand their business data through natural language.
6154
-
6155
- Always answer in the same language the user is using. Detailed tool-usage guidance is supplied by the skills attached to this agent.`,
6156
- model: {
6157
- provider: "openai",
6158
- model: "gpt-4",
6159
- temperature: 0.3,
6160
- maxTokens: 4096
6161
- },
6162
- // Capability bundle lives on the skill; the agent only references it.
6163
- // `data_explorer` = read side, `actions_executor` = write side.
6164
- skills: ["data_explorer", "actions_executor"],
6165
- active: true,
6166
- visibility: "global",
6167
- guardrails: {
6168
- maxTokensPerInvocation: 8192,
6169
- maxExecutionTimeSec: 30,
6170
- blockedTopics: ["delete_records", "drop_table", "alter_schema"]
6171
- },
6172
- planning: {
6173
- strategy: "react",
6174
- maxIterations: 5,
6175
- allowReplan: false
6176
- },
6177
- memory: {
6178
- shortTerm: {
6179
- maxMessages: 20,
6180
- maxTokens: 4096
6181
- }
6182
- }
6183
- };
6184
-
6185
- // src/agents/metadata-assistant-agent.ts
6186
- var METADATA_ASSISTANT_AGENT = {
6187
- name: "metadata_assistant",
6188
- label: "Metadata Assistant",
6189
- role: "Schema Architect",
6190
- instructions: `You are an expert metadata architect that helps users design and manage their data models through natural language.
6191
-
6192
- Always answer in the same language the user is using. If the user's request is ambiguous, ask clarifying questions before proceeding. Detailed tool-usage guidance is supplied by the skills attached to this agent.`,
6193
- model: {
6194
- provider: "openai",
6195
- model: "gpt-4",
6196
- temperature: 0.2,
6197
- maxTokens: 4096
6198
- },
6199
- // Capability bundle lives on the skill; the agent only references it.
6200
- skills: ["metadata_authoring"],
6201
- active: true,
6202
- visibility: "global",
6203
- guardrails: {
6204
- maxTokensPerInvocation: 8192,
6205
- maxExecutionTimeSec: 60,
6206
- blockedTopics: ["drop_database", "raw_sql", "system_tables"]
6207
- },
6208
- planning: {
6209
- strategy: "react",
6210
- maxIterations: 10,
6211
- allowReplan: true
6212
- },
6213
- memory: {
6214
- shortTerm: {
6215
- maxMessages: 30,
6216
- maxTokens: 8192
6217
- }
6218
- }
6219
- };
6220
-
6221
6236
  // src/skills/data-explorer-skill.ts
6222
6237
  var DATA_EXPLORER_SKILL = {
6223
6238
  name: "data_explorer",
@@ -6784,7 +6799,7 @@ var _AIServicePlugin = class _AIServicePlugin {
6784
6799
  );
6785
6800
  const provider = mod[factory] ?? mod.default;
6786
6801
  if (typeof provider === "function") {
6787
- const modelId = process.env.AI_MODEL ?? defaultModel;
6802
+ const modelId = (0, import_types.readEnvWithDeprecation)("OS_AI_MODEL", "AI_MODEL") ?? defaultModel;
6788
6803
  const useChatApi = factory === "openai" && typeof provider.chat === "function";
6789
6804
  const model = useChatApi ? provider.chat(modelId) : provider(modelId);
6790
6805
  const adapter = new VercelLLMAdapter({ model });
@@ -6877,7 +6892,7 @@ var _AIServicePlugin = class _AIServicePlugin {
6877
6892
  name: "AI Service",
6878
6893
  version: "1.0.0",
6879
6894
  type: "plugin",
6880
- scope: "project",
6895
+ scope: "system",
6881
6896
  namespace: "ai",
6882
6897
  objects: [AiConversationObject, AiMessageObject, AiTraceObject, AiPendingActionObject, AiEvalCaseObject, AiEvalRunObject],
6883
6898
  views: [AiTraceView, AiMessageView, AiPendingActionView, AiEvalCaseView, AiEvalRunView]
@@ -6980,7 +6995,8 @@ var _AIServicePlugin = class _AIServicePlugin {
6980
6995
  }
6981
6996
  if (!toolExists) {
6982
6997
  try {
6983
- await withTimeout(metadataService.register("tool", toolDef.name, toolDef));
6998
+ const label = toolDef.label ?? toToolLabel(toolDef.name);
6999
+ await withTimeout(metadataService.register("tool", toolDef.name, { ...toolDef, label }));
6984
7000
  } catch (err) {
6985
7001
  ctx.logger.warn(
6986
7002
  "[AI] Failed to persist tool metadata (non-fatal)",
@@ -7398,6 +7414,9 @@ _AIServicePlugin.OPENAI_COMPATIBLE_PRESETS = {
7398
7414
  openrouter: { baseURL: "https://openrouter.ai/api/v1", defaultModel: "openai/gpt-4o-mini" }
7399
7415
  };
7400
7416
  var AIServicePlugin = _AIServicePlugin;
7417
+ function toToolLabel(name) {
7418
+ return name.split("_").filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
7419
+ }
7401
7420
  function extractOverrides(payload) {
7402
7421
  if (!payload || typeof payload !== "object") return {};
7403
7422
  const p = payload;