graphlit-client 1.0.20260418001 → 1.0.20260419002

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/client.d.ts CHANGED
@@ -1601,6 +1601,91 @@ declare class Graphlit {
1601
1601
  * @returns The matching persons.
1602
1602
  */
1603
1603
  lookupPersons(linkedInUrl?: string, email?: string): Promise<Types.LookupPersonsQuery>;
1604
+ /**
1605
+ * Creates a replica.
1606
+ * @param replica - The replica to create.
1607
+ * @returns The created replica.
1608
+ */
1609
+ createReplica(replica: Types.ReplicaInput): Promise<Types.CreateReplicaMutation>;
1610
+ /**
1611
+ * Updates a replica.
1612
+ * @param replica - The replica to update.
1613
+ * @returns The updated replica.
1614
+ */
1615
+ updateReplica(replica: Types.ReplicaUpdateInput): Promise<Types.UpdateReplicaMutation>;
1616
+ /**
1617
+ * Creates or updates a replica.
1618
+ * @param replica - The replica to create or update.
1619
+ * @returns The created or updated replica.
1620
+ */
1621
+ upsertReplica(replica: Types.ReplicaInput): Promise<Types.UpsertReplicaMutation>;
1622
+ /**
1623
+ * Deletes a replica.
1624
+ * @param id - The ID of the replica to delete.
1625
+ * @returns The deleted replica.
1626
+ */
1627
+ deleteReplica(id: string): Promise<Types.DeleteReplicaMutation>;
1628
+ /**
1629
+ * Deletes multiple replicas.
1630
+ * @param ids - The IDs of the replicas to delete.
1631
+ * @param isSynchronous - Whether this mutation is synchronous.
1632
+ * @returns The deleted replicas.
1633
+ */
1634
+ deleteReplicas(ids: string[], isSynchronous?: boolean): Promise<Types.DeleteReplicasMutation>;
1635
+ /**
1636
+ * Deletes all replicas based on the provided filter criteria.
1637
+ * @param filter - The filter criteria to apply when deleting replicas.
1638
+ * @param isSynchronous - Whether this mutation is synchronous.
1639
+ * @param correlationId - The tenant correlation identifier, optional.
1640
+ * @returns The result of the deletion.
1641
+ */
1642
+ deleteAllReplicas(filter?: Types.ReplicaFilter, isSynchronous?: boolean, correlationId?: string): Promise<Types.DeleteAllReplicasMutation>;
1643
+ /**
1644
+ * Triggers a replica to run immediately.
1645
+ * @param id - The ID of the replica to trigger.
1646
+ * @returns The triggered replica.
1647
+ */
1648
+ triggerReplica(id: string): Promise<Types.TriggerReplicaMutation>;
1649
+ /**
1650
+ * Enables a replica.
1651
+ * @param id - The ID of the replica to enable.
1652
+ * @returns The enabled replica.
1653
+ */
1654
+ enableReplica(id: string): Promise<Types.EnableReplicaMutation>;
1655
+ /**
1656
+ * Disables a replica.
1657
+ * @param id - The ID of the replica to disable.
1658
+ * @returns The disabled replica.
1659
+ */
1660
+ disableReplica(id: string): Promise<Types.DisableReplicaMutation>;
1661
+ /**
1662
+ * Lookup a replica given its ID.
1663
+ * @param id - ID of the replica.
1664
+ * @param correlationId - The tenant correlation identifier, optional.
1665
+ * @returns The replica.
1666
+ */
1667
+ getReplica(id: string, correlationId?: string): Promise<Types.GetReplicaQuery>;
1668
+ /**
1669
+ * Retrieves replicas based on the provided filter criteria.
1670
+ * @param filter - The filter criteria to apply when retrieving replicas.
1671
+ * @param correlationId - The tenant correlation identifier, optional.
1672
+ * @returns The replicas.
1673
+ */
1674
+ queryReplicas(filter?: Types.ReplicaFilter, correlationId?: string): Promise<Types.QueryReplicasQuery>;
1675
+ /**
1676
+ * Counts replicas based on the provided filter criteria.
1677
+ * @param filter - The filter criteria to apply when counting replicas.
1678
+ * @param correlationId - The tenant correlation identifier, optional.
1679
+ * @returns The count of replicas.
1680
+ */
1681
+ countReplicas(filter?: Types.ReplicaFilter, correlationId?: string): Promise<Types.CountReplicasQuery>;
1682
+ /**
1683
+ * Checks if a replica exists based on the provided filter criteria.
1684
+ * @param filter - The filter criteria to apply.
1685
+ * @param correlationId - The tenant correlation identifier, optional.
1686
+ * @returns Whether the replica exists.
1687
+ */
1688
+ replicaExists(filter?: Types.ReplicaFilter, correlationId?: string): Promise<Types.ReplicaExistsQuery>;
1604
1689
  /**
1605
1690
  * Creates a skill.
1606
1691
  * @param skill - The skill to create.
@@ -3012,9 +3097,28 @@ declare class Graphlit {
3012
3097
  */
3013
3098
  private reconstructTurnResults;
3014
3099
  /**
3015
- * Extract task_complete summary from intermediate messages.
3100
+ * Detect whether task_complete was invoked in a single list of tool calls.
3101
+ *
3102
+ * Recognizes two invocation shapes:
3103
+ * 1. Direct — a tool call whose `name` is `"task_complete"`.
3104
+ * 2. Wrapped — a tool call whose arguments JSON has shape
3105
+ * `{ tool: "task_complete", parameters: { ... } }`. This is the common
3106
+ * pattern used by dynamic-toolset clients that expose a single
3107
+ * meta-executor (often named `execute_tool`) at the top level and
3108
+ * route every underlying tool through it.
3109
+ *
3110
+ * Detection is invocation-agnostic: whether the model called task_complete
3111
+ * directly or via a meta-executor, the harness treats the turn as complete.
3112
+ * Callers that only register a direct top-level task_complete still work —
3113
+ * the wrapped path is simply inert when no meta-executor is in use.
3114
+ */
3115
+ private detectTaskComplete;
3116
+ /**
3117
+ * Scan a list of messages for a task_complete invocation. Convenience
3118
+ * wrapper over `detectTaskComplete` for the streamAgent loop, which works
3119
+ * with `intermediateMessages` rather than a single tool-call list.
3016
3120
  */
3017
- private extractTaskCompleteSummary;
3121
+ private detectTaskCompleteInMessages;
3018
3122
  /**
3019
3123
  * Run LLM-as-judge quality assessment on a completed agent run.
3020
3124
  */
package/dist/client.js CHANGED
@@ -2878,11 +2878,136 @@ class Graphlit {
2878
2878
  });
2879
2879
  }
2880
2880
  // ──────────────────────────────────────────────────────────────────────────
2881
+ // Replicas
2882
+ // ──────────────────────────────────────────────────────────────────────────
2883
+ /**
2884
+ * Creates a replica.
2885
+ * @param replica - The replica to create.
2886
+ * @returns The created replica.
2887
+ */
2888
+ async createReplica(replica) {
2889
+ return this.mutateAndCheckError(Documents.CreateReplica, {
2890
+ replica: replica,
2891
+ });
2892
+ }
2893
+ /**
2894
+ * Updates a replica.
2895
+ * @param replica - The replica to update.
2896
+ * @returns The updated replica.
2897
+ */
2898
+ async updateReplica(replica) {
2899
+ return this.mutateAndCheckError(Documents.UpdateReplica, { replica: replica });
2900
+ }
2901
+ /**
2902
+ * Creates or updates a replica.
2903
+ * @param replica - The replica to create or update.
2904
+ * @returns The created or updated replica.
2905
+ */
2906
+ async upsertReplica(replica) {
2907
+ return this.mutateAndCheckError(Documents.UpsertReplica, { replica: replica });
2908
+ }
2909
+ /**
2910
+ * Deletes a replica.
2911
+ * @param id - The ID of the replica to delete.
2912
+ * @returns The deleted replica.
2913
+ */
2914
+ async deleteReplica(id) {
2915
+ return this.mutateAndCheckError(Documents.DeleteReplica, { id: id });
2916
+ }
2917
+ /**
2918
+ * Deletes multiple replicas.
2919
+ * @param ids - The IDs of the replicas to delete.
2920
+ * @param isSynchronous - Whether this mutation is synchronous.
2921
+ * @returns The deleted replicas.
2922
+ */
2923
+ async deleteReplicas(ids, isSynchronous) {
2924
+ return this.mutateAndCheckError(Documents.DeleteReplicas, { ids: ids, isSynchronous: isSynchronous });
2925
+ }
2926
+ /**
2927
+ * Deletes all replicas based on the provided filter criteria.
2928
+ * @param filter - The filter criteria to apply when deleting replicas.
2929
+ * @param isSynchronous - Whether this mutation is synchronous.
2930
+ * @param correlationId - The tenant correlation identifier, optional.
2931
+ * @returns The result of the deletion.
2932
+ */
2933
+ async deleteAllReplicas(filter, isSynchronous, correlationId) {
2934
+ return this.mutateAndCheckError(Documents.DeleteAllReplicas, {
2935
+ filter: filter,
2936
+ isSynchronous: isSynchronous,
2937
+ correlationId: correlationId,
2938
+ });
2939
+ }
2940
+ /**
2941
+ * Triggers a replica to run immediately.
2942
+ * @param id - The ID of the replica to trigger.
2943
+ * @returns The triggered replica.
2944
+ */
2945
+ async triggerReplica(id) {
2946
+ return this.mutateAndCheckError(Documents.TriggerReplica, { id: id });
2947
+ }
2948
+ /**
2949
+ * Enables a replica.
2950
+ * @param id - The ID of the replica to enable.
2951
+ * @returns The enabled replica.
2952
+ */
2953
+ async enableReplica(id) {
2954
+ return this.mutateAndCheckError(Documents.EnableReplica, { id: id });
2955
+ }
2956
+ /**
2957
+ * Disables a replica.
2958
+ * @param id - The ID of the replica to disable.
2959
+ * @returns The disabled replica.
2960
+ */
2961
+ async disableReplica(id) {
2962
+ return this.mutateAndCheckError(Documents.DisableReplica, { id: id });
2963
+ }
2964
+ /**
2965
+ * Lookup a replica given its ID.
2966
+ * @param id - ID of the replica.
2967
+ * @param correlationId - The tenant correlation identifier, optional.
2968
+ * @returns The replica.
2969
+ */
2970
+ async getReplica(id, correlationId) {
2971
+ return this.queryAndCheckError(Documents.GetReplica, { id: id, correlationId: correlationId });
2972
+ }
2973
+ /**
2974
+ * Retrieves replicas based on the provided filter criteria.
2975
+ * @param filter - The filter criteria to apply when retrieving replicas.
2976
+ * @param correlationId - The tenant correlation identifier, optional.
2977
+ * @returns The replicas.
2978
+ */
2979
+ async queryReplicas(filter, correlationId) {
2980
+ return this.queryAndCheckError(Documents.QueryReplicas, {
2981
+ filter: filter,
2982
+ correlationId: correlationId,
2983
+ });
2984
+ }
2985
+ /**
2986
+ * Counts replicas based on the provided filter criteria.
2987
+ * @param filter - The filter criteria to apply when counting replicas.
2988
+ * @param correlationId - The tenant correlation identifier, optional.
2989
+ * @returns The count of replicas.
2990
+ */
2991
+ async countReplicas(filter, correlationId) {
2992
+ return this.queryAndCheckError(Documents.CountReplicas, {
2993
+ filter: filter,
2994
+ correlationId: correlationId,
2995
+ });
2996
+ }
2997
+ /**
2998
+ * Checks if a replica exists based on the provided filter criteria.
2999
+ * @param filter - The filter criteria to apply.
3000
+ * @param correlationId - The tenant correlation identifier, optional.
3001
+ * @returns Whether the replica exists.
3002
+ */
3003
+ async replicaExists(filter, correlationId) {
3004
+ return this.queryAndCheckError(Documents.ReplicaExists, {
3005
+ filter: filter,
3006
+ correlationId: correlationId,
3007
+ });
3008
+ }
3009
+ // ──────────────────────────────────────────────────────────────────────────
2881
3010
  // Skills
2882
- // NOTE: Types (SkillInput, SkillUpdateInput, SkillFilter, etc.) and
2883
- // Documents (CreateSkill, UpdateSkill, etc.) will be generated by codegen
2884
- // once the API schema is published. Until then these methods will show
2885
- // TypeScript errors — that is expected.
2886
3011
  // ──────────────────────────────────────────────────────────────────────────
2887
3012
  /**
2888
3013
  * Creates a skill.
@@ -6752,7 +6877,6 @@ class Graphlit {
6752
6877
  let totalToolCalls = 0;
6753
6878
  let status = "completed";
6754
6879
  let finalMessage = "";
6755
- let taskCompleteSummary;
6756
6880
  let stuckPattern;
6757
6881
  let errorMessage;
6758
6882
  let lastContextWindow;
@@ -6855,23 +6979,24 @@ class Graphlit {
6855
6979
  evaluator.adjustBudget(multiplier);
6856
6980
  }
6857
6981
  }
6858
- // Build tools list with task_complete prepended
6982
+ // Build tools list with task_complete prepended.
6983
+ //
6984
+ // task_complete is a bare completion signal — it takes no arguments.
6985
+ // The agent's user-facing answer MUST be in its final assistant message
6986
+ // (the `fullMessage` / `finalAssistantMessage` on the turn result); this
6987
+ // tool only marks the run as done.
6988
+ //
6989
+ // Earlier versions had a `summary` field. That consistently caused the
6990
+ // model to stuff its answer into the tool argument and then write a
6991
+ // useless prose message ("answer delivered above") — the user would see
6992
+ // the empty prose, not the answer. Removing the field eliminates the
6993
+ // hiding place.
6859
6994
  const taskCompleteTool = {
6860
6995
  name: "task_complete",
6861
- description: "Call this tool when you have completed the assigned task. Provide a summary of what was accomplished and any recommendations.",
6996
+ description: "Signal that you have completed the assigned task. Your full answer must already be in your assistant message BEFORE calling this — that prose is what the user sees. This tool takes no arguments; it only ends the run.",
6862
6997
  schema: JSON.stringify({
6863
6998
  type: "object",
6864
- properties: {
6865
- summary: {
6866
- type: "string",
6867
- description: "Summary of what was accomplished.",
6868
- },
6869
- recommendations: {
6870
- type: "string",
6871
- description: "Optional recommendations or next steps.",
6872
- },
6873
- },
6874
- required: ["summary"],
6999
+ properties: {},
6875
7000
  }),
6876
7001
  };
6877
7002
  const allTools = [
@@ -7168,7 +7293,7 @@ class Graphlit {
7168
7293
  }
7169
7294
  // 9. Build TurnResult
7170
7295
  const turnDuration = Date.now() - turnStart;
7171
- const taskCompleteThisTurn = loopResult.toolCallNames.includes("task_complete");
7296
+ const taskCompleteThisTurn = this.detectTaskCompleteInMessages(loopResult.intermediateMessages);
7172
7297
  const turnToolNames = [...new Set(loopResult.toolCallNames)].sort();
7173
7298
  const turnResult = {
7174
7299
  turnNumber: turn,
@@ -7196,8 +7321,6 @@ class Graphlit {
7196
7321
  // 11. Evaluate turn
7197
7322
  // a. task_complete called?
7198
7323
  if (taskCompleteThisTurn) {
7199
- // Extract summary from task_complete arguments
7200
- taskCompleteSummary = this.extractTaskCompleteSummary(loopResult.intermediateMessages);
7201
7324
  status = "completed";
7202
7325
  break;
7203
7326
  }
@@ -7236,9 +7359,13 @@ class Graphlit {
7236
7359
  // f. Set next prompt
7237
7360
  currentPrompt = "Continue.";
7238
7361
  }
7239
- // If we exited the loop without an explicit status change, check budget
7362
+ // If we exited the loop without an explicit status change, check budget.
7363
+ // status defaults to "completed", so we need a positive signal that
7364
+ // task_complete was actually called — otherwise hitting the turn cap
7365
+ // looks like success.
7366
+ const taskCompleteWasCalled = turnResults.some((t) => t.taskComplete);
7240
7367
  if (status === "completed" &&
7241
- !taskCompleteSummary &&
7368
+ !taskCompleteWasCalled &&
7242
7369
  turnResults.length >= evaluator.adjustedMaxTurns) {
7243
7370
  status = "budget_exhausted";
7244
7371
  }
@@ -7254,7 +7381,6 @@ class Graphlit {
7254
7381
  conversationId,
7255
7382
  status,
7256
7383
  finalMessage,
7257
- taskCompleteSummary,
7258
7384
  turnResults,
7259
7385
  totalToolCalls,
7260
7386
  wallClockMs,
@@ -7281,7 +7407,6 @@ class Graphlit {
7281
7407
  conversationId,
7282
7408
  status,
7283
7409
  finalMessage,
7284
- taskCompleteSummary,
7285
7410
  turnResults,
7286
7411
  totalToolCalls,
7287
7412
  wallClockMs: Date.now() - runStart,
@@ -7382,32 +7507,62 @@ class Graphlit {
7382
7507
  toolCalls: [...new Set(toolNames)].sort(),
7383
7508
  toolCallCount: toolNames.length,
7384
7509
  durationMs: computePersistedToolRoundDurationMs(assistantMsg.toolCalls) ?? 0,
7385
- taskComplete: toolNames.includes("task_complete"),
7510
+ taskComplete: this.detectTaskComplete(assistantMsg.toolCalls),
7386
7511
  errors: toolErrors.length > 0 ? toolErrors : undefined,
7387
7512
  });
7388
7513
  }
7389
7514
  return results;
7390
7515
  }
7391
7516
  /**
7392
- * Extract task_complete summary from intermediate messages.
7393
- */
7394
- extractTaskCompleteSummary(messages) {
7395
- for (const msg of messages) {
7396
- if (msg.toolCalls) {
7397
- for (const tc of msg.toolCalls) {
7398
- if (tc && tc.name === "task_complete" && tc.arguments) {
7399
- try {
7400
- const args = JSON.parse(tc.arguments);
7401
- return args.summary ?? undefined;
7402
- }
7403
- catch {
7404
- return undefined;
7405
- }
7406
- }
7517
+ * Detect whether task_complete was invoked in a single list of tool calls.
7518
+ *
7519
+ * Recognizes two invocation shapes:
7520
+ * 1. Direct a tool call whose `name` is `"task_complete"`.
7521
+ * 2. Wrapped — a tool call whose arguments JSON has shape
7522
+ * `{ tool: "task_complete", parameters: { ... } }`. This is the common
7523
+ * pattern used by dynamic-toolset clients that expose a single
7524
+ * meta-executor (often named `execute_tool`) at the top level and
7525
+ * route every underlying tool through it.
7526
+ *
7527
+ * Detection is invocation-agnostic: whether the model called task_complete
7528
+ * directly or via a meta-executor, the harness treats the turn as complete.
7529
+ * Callers that only register a direct top-level task_complete still work —
7530
+ * the wrapped path is simply inert when no meta-executor is in use.
7531
+ */
7532
+ detectTaskComplete(toolCalls) {
7533
+ if (!toolCalls)
7534
+ return false;
7535
+ for (const tc of toolCalls) {
7536
+ if (!tc)
7537
+ continue;
7538
+ // Direct invocation
7539
+ if (tc.name === "task_complete")
7540
+ return true;
7541
+ // Meta-executor wrapping (e.g. execute_tool({ tool: "task_complete", parameters: {...} }))
7542
+ if (tc.arguments) {
7543
+ try {
7544
+ const args = JSON.parse(tc.arguments);
7545
+ if (args.tool === "task_complete")
7546
+ return true;
7547
+ }
7548
+ catch {
7549
+ // Not JSON — skip
7407
7550
  }
7408
7551
  }
7409
7552
  }
7410
- return undefined;
7553
+ return false;
7554
+ }
7555
+ /**
7556
+ * Scan a list of messages for a task_complete invocation. Convenience
7557
+ * wrapper over `detectTaskComplete` for the streamAgent loop, which works
7558
+ * with `intermediateMessages` rather than a single tool-call list.
7559
+ */
7560
+ detectTaskCompleteInMessages(messages) {
7561
+ for (const msg of messages) {
7562
+ if (this.detectTaskComplete(msg.toolCalls))
7563
+ return true;
7564
+ }
7565
+ return false;
7411
7566
  }
7412
7567
  /**
7413
7568
  * Run LLM-as-judge quality assessment on a completed agent run.
@@ -7488,7 +7643,6 @@ class Graphlit {
7488
7643
  conversationId: params.conversationId,
7489
7644
  status: params.status,
7490
7645
  finalMessage: params.finalMessage,
7491
- taskCompleteSummary: params.taskCompleteSummary,
7492
7646
  turns: params.turnResults.length,
7493
7647
  totalToolCalls: params.totalToolCalls,
7494
7648
  wallClockMs: params.wallClockMs,
@@ -412,6 +412,19 @@ export declare const QueryCredits: import("graphql").DocumentNode;
412
412
  export declare const QueryTokens: import("graphql").DocumentNode;
413
413
  export declare const QueryUsage: import("graphql").DocumentNode;
414
414
  export declare const UpdateProject: import("graphql").DocumentNode;
415
+ export declare const CountReplicas: import("graphql").DocumentNode;
416
+ export declare const CreateReplica: import("graphql").DocumentNode;
417
+ export declare const DeleteAllReplicas: import("graphql").DocumentNode;
418
+ export declare const DeleteReplica: import("graphql").DocumentNode;
419
+ export declare const DeleteReplicas: import("graphql").DocumentNode;
420
+ export declare const DisableReplica: import("graphql").DocumentNode;
421
+ export declare const EnableReplica: import("graphql").DocumentNode;
422
+ export declare const GetReplica: import("graphql").DocumentNode;
423
+ export declare const QueryReplicas: import("graphql").DocumentNode;
424
+ export declare const ReplicaExists: import("graphql").DocumentNode;
425
+ export declare const TriggerReplica: import("graphql").DocumentNode;
426
+ export declare const UpdateReplica: import("graphql").DocumentNode;
427
+ export declare const UpsertReplica: import("graphql").DocumentNode;
415
428
  export declare const CountRepos: import("graphql").DocumentNode;
416
429
  export declare const CreateRepo: import("graphql").DocumentNode;
417
430
  export declare const DeleteAllRepos: import("graphql").DocumentNode;