@questionbase/deskfree 0.3.0-alpha.20 → 0.3.0-alpha.21
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 +1 -1
- package/dist/index.d.ts +47 -25
- package/dist/index.js +259 -81
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/deskfree/SKILL.md +222 -48
- package/skills/deskfree/references/tools.md +65 -24
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Agents can pick up tasks, post progress updates, mark work as done or blocked, m
|
|
|
15
15
|
│ deskfree_state Inbound messages from humans │
|
|
16
16
|
│ deskfree_start_task Outbound replies from agent │
|
|
17
17
|
│ deskfree_complete_task Real-time notifications │
|
|
18
|
-
│
|
|
18
|
+
│ deskfree_suggest_tasks │
|
|
19
19
|
│ deskfree_create_activity │
|
|
20
20
|
│ deskfree_update_activity │
|
|
21
21
|
│ deskfree_classify_task │
|
package/dist/index.d.ts
CHANGED
|
@@ -442,13 +442,6 @@ interface TaskWithContext extends Task {
|
|
|
442
442
|
deliverable: string;
|
|
443
443
|
messages: TaskMessage[];
|
|
444
444
|
}
|
|
445
|
-
/**
|
|
446
|
-
* Response from the tasks.create bot endpoint.
|
|
447
|
-
*
|
|
448
|
-
* The backend mutation (`trpc.bot.tasks.create`) returns the Task object
|
|
449
|
-
* directly (not wrapped in `{ task: ... }`).
|
|
450
|
-
*/
|
|
451
|
-
type CreateTaskResponse = Task;
|
|
452
445
|
interface CompleteTaskInput {
|
|
453
446
|
taskId: string;
|
|
454
447
|
outcome: 'done' | 'blocked';
|
|
@@ -463,6 +456,15 @@ interface WorkspaceStateTask {
|
|
|
463
456
|
createdAt: string;
|
|
464
457
|
updatedAt: string;
|
|
465
458
|
}
|
|
459
|
+
interface Initiative {
|
|
460
|
+
id: string;
|
|
461
|
+
title: string;
|
|
462
|
+
status: 'suggested' | 'active' | 'paused';
|
|
463
|
+
content: string;
|
|
464
|
+
contentVersion: number;
|
|
465
|
+
taskCount: number;
|
|
466
|
+
activeTaskCount: number;
|
|
467
|
+
}
|
|
466
468
|
interface WorkspaceState {
|
|
467
469
|
tasks: WorkspaceStateTask[];
|
|
468
470
|
recentlyDone: WorkspaceStateTask[];
|
|
@@ -471,7 +473,9 @@ interface WorkspaceState {
|
|
|
471
473
|
taskId: string;
|
|
472
474
|
taskNumber: number;
|
|
473
475
|
title: string;
|
|
476
|
+
initiativeId?: string | null;
|
|
474
477
|
}>;
|
|
478
|
+
initiatives: Initiative[];
|
|
475
479
|
}
|
|
476
480
|
interface EvaluationTaskMessage {
|
|
477
481
|
messageId: string;
|
|
@@ -487,6 +491,11 @@ interface ClaimEvaluationResponse {
|
|
|
487
491
|
waysOfWorking: string | null;
|
|
488
492
|
currentVersion: number;
|
|
489
493
|
messages: EvaluationTaskMessage[];
|
|
494
|
+
initiative?: {
|
|
495
|
+
id: string;
|
|
496
|
+
title: string;
|
|
497
|
+
content: string;
|
|
498
|
+
} | null;
|
|
490
499
|
}
|
|
491
500
|
|
|
492
501
|
/** Enhanced error class for DeskFree API errors with user-friendly messages */
|
|
@@ -558,19 +567,6 @@ declare class DeskFreeClient {
|
|
|
558
567
|
}): Promise<MessagesResponse>;
|
|
559
568
|
/** Obtain a one-time WebSocket authentication ticket for real-time notifications. */
|
|
560
569
|
getWsTicket(): Promise<WsTicketResponse>;
|
|
561
|
-
/** Create a new task, optionally with a recurring schedule. */
|
|
562
|
-
createTask(input: {
|
|
563
|
-
title: string;
|
|
564
|
-
instructions?: string;
|
|
565
|
-
isRecurring?: boolean;
|
|
566
|
-
recurringSchedule?: {
|
|
567
|
-
frequency: 'daily' | 'weekly' | 'biweekly' | 'monthly';
|
|
568
|
-
dayOfWeek?: number;
|
|
569
|
-
dayOfMonth?: number;
|
|
570
|
-
time: string;
|
|
571
|
-
timezone?: string;
|
|
572
|
-
};
|
|
573
|
-
}): Promise<CreateTaskResponse>;
|
|
574
570
|
/** Claim a task so the bot can begin working on it. Returns enriched context. */
|
|
575
571
|
claimTask(input: {
|
|
576
572
|
taskId: string;
|
|
@@ -638,6 +634,25 @@ declare class DeskFreeClient {
|
|
|
638
634
|
messageId: string;
|
|
639
635
|
content: string;
|
|
640
636
|
}>;
|
|
637
|
+
/** Suggest tasks via the dedicated bot/tasks.suggest endpoint. */
|
|
638
|
+
suggestTasksDedicated(input: {
|
|
639
|
+
suggestions: Array<{
|
|
640
|
+
title: string;
|
|
641
|
+
instructions?: string;
|
|
642
|
+
estimatedTokens?: number;
|
|
643
|
+
dependsOn?: string[];
|
|
644
|
+
initiativeId?: string;
|
|
645
|
+
}>;
|
|
646
|
+
parentTaskId?: string;
|
|
647
|
+
initiativeSuggestions?: Array<{
|
|
648
|
+
title: string;
|
|
649
|
+
content: string;
|
|
650
|
+
taskRefs?: number[];
|
|
651
|
+
}>;
|
|
652
|
+
}): Promise<{
|
|
653
|
+
suggestionIds: string[];
|
|
654
|
+
initiativeSuggestionIds?: string[];
|
|
655
|
+
}>;
|
|
641
656
|
/**
|
|
642
657
|
* Claim a pending evaluation for a task. Atomically sets isWorking=true where
|
|
643
658
|
* evaluationPending=true and isWorking=false. Returns null if already claimed.
|
|
@@ -647,17 +662,24 @@ declare class DeskFreeClient {
|
|
|
647
662
|
}): Promise<ClaimEvaluationResponse | null>;
|
|
648
663
|
/**
|
|
649
664
|
* Submit the result of a ways-of-working evaluation.
|
|
650
|
-
*
|
|
665
|
+
* Dual output: globalWoW (applies everywhere) and initiative (applies to the task's initiative).
|
|
651
666
|
* Clears evaluationPending and isWorking on the task.
|
|
652
667
|
*/
|
|
653
668
|
submitEvaluation(input: {
|
|
654
669
|
taskId: string;
|
|
655
|
-
updatedContent?: string;
|
|
656
670
|
reasoning: string;
|
|
657
|
-
|
|
671
|
+
globalWoW: {
|
|
672
|
+
hasChanges: boolean;
|
|
673
|
+
updatedContent?: string;
|
|
674
|
+
};
|
|
675
|
+
initiative: {
|
|
676
|
+
hasChanges: boolean;
|
|
677
|
+
updatedContent?: string;
|
|
678
|
+
};
|
|
658
679
|
}): Promise<{
|
|
659
680
|
success: boolean;
|
|
660
|
-
|
|
681
|
+
globalVersion?: number;
|
|
682
|
+
initiativeVersion?: number;
|
|
661
683
|
}>;
|
|
662
684
|
/**
|
|
663
685
|
* Lightweight health check that verifies connectivity and authentication.
|
|
@@ -725,4 +747,4 @@ declare const plugin: {
|
|
|
725
747
|
register(api: OpenClawPluginApi): void;
|
|
726
748
|
};
|
|
727
749
|
|
|
728
|
-
export { type AnyAgentTool, type ChannelAccountSnapshot, type ChannelCapabilities, type ChannelConfigAdapter, type ChannelGatewayAdapter, type ChannelGatewayContext, type ChannelLogoutContext, type ChannelLogoutResult, type ChannelMessagingAdapter, type ChannelMessagingTargetResolver, type ChannelMeta, type ChannelOnboardingAdapter, type ChannelOnboardingResult, type ChannelOnboardingStatus, type ChannelOutboundAdapter, type ChannelOutboundContext, type ChannelPlugin, type ChannelProbeResult, type ChannelSecurityAdapter, type ChannelSecurityDmPolicy, type ChannelSetupAdapter, type ChannelStatusAdapter, type ChannelStatusIssue, type ChatMessage, type ChatMessageAttachment, type ClaimEvaluationResponse, type CompleteTaskInput, type
|
|
750
|
+
export { type AnyAgentTool, type ChannelAccountSnapshot, type ChannelCapabilities, type ChannelConfigAdapter, type ChannelGatewayAdapter, type ChannelGatewayContext, type ChannelLogoutContext, type ChannelLogoutResult, type ChannelMessagingAdapter, type ChannelMessagingTargetResolver, type ChannelMeta, type ChannelOnboardingAdapter, type ChannelOnboardingResult, type ChannelOnboardingStatus, type ChannelOutboundAdapter, type ChannelOutboundContext, type ChannelPlugin, type ChannelProbeResult, type ChannelSecurityAdapter, type ChannelSecurityDmPolicy, type ChannelSetupAdapter, type ChannelStatusAdapter, type ChannelStatusIssue, type ChatMessage, type ChatMessageAttachment, type ClaimEvaluationResponse, type CompleteTaskInput, type DeskFreeChannelConfig, DeskFreeClient, DeskFreeError, type EvaluationTaskMessage, type FinalizedMsgContext, type Initiative, type MessagesResponse, OfflineQueue, type OpenClawConfig, type OpenClawPluginApi, type OpenClawPluginToolContext, type OpenClawPluginToolFactory, type OpenClawPluginToolOptions, type OutboundDeliveryResult, type PluginHookAgentContext, type PluginHookBeforeAgentStartEvent, type PluginHookBeforeAgentStartResult, type PluginHookHandlerMap, type PluginHookName, type PluginLogger, type PluginRuntime, type ReplyDispatcher, type ResolvedDeskFreeAccount, type Task, type TaskMessage, type TaskWithContext, type WizardPrompter, type WorkspaceState, type WorkspaceStateTask, type WsNotification, type WsTicketResponse, plugin as default, reportError };
|
package/dist/index.js
CHANGED
|
@@ -3889,11 +3889,6 @@ var DeskFreeClient = class {
|
|
|
3889
3889
|
return this.request("POST", "messages.wsTicket", {});
|
|
3890
3890
|
}
|
|
3891
3891
|
// ── Tasks ─────────────────────────────────────────────────
|
|
3892
|
-
/** Create a new task, optionally with a recurring schedule. */
|
|
3893
|
-
async createTask(input) {
|
|
3894
|
-
this.requireNonEmpty(input.title, "title");
|
|
3895
|
-
return this.request("POST", "tasks.create", input);
|
|
3896
|
-
}
|
|
3897
3892
|
/** Claim a task so the bot can begin working on it. Returns enriched context. */
|
|
3898
3893
|
async claimTask(input) {
|
|
3899
3894
|
this.requireNonEmpty(input.taskId, "taskId");
|
|
@@ -3943,6 +3938,18 @@ var DeskFreeClient = class {
|
|
|
3943
3938
|
taskId: input.taskId
|
|
3944
3939
|
});
|
|
3945
3940
|
}
|
|
3941
|
+
/** Suggest tasks via the dedicated bot/tasks.suggest endpoint. */
|
|
3942
|
+
async suggestTasksDedicated(input) {
|
|
3943
|
+
if (!input.suggestions || input.suggestions.length === 0) {
|
|
3944
|
+
throw new DeskFreeError(
|
|
3945
|
+
"client",
|
|
3946
|
+
"suggestions",
|
|
3947
|
+
"suggestions array is required and cannot be empty",
|
|
3948
|
+
"Missing required parameter: suggestions."
|
|
3949
|
+
);
|
|
3950
|
+
}
|
|
3951
|
+
return this.request("POST", "tasks.suggest", input);
|
|
3952
|
+
}
|
|
3946
3953
|
/**
|
|
3947
3954
|
* Claim a pending evaluation for a task. Atomically sets isWorking=true where
|
|
3948
3955
|
* evaluationPending=true and isWorking=false. Returns null if already claimed.
|
|
@@ -3953,7 +3960,7 @@ var DeskFreeClient = class {
|
|
|
3953
3960
|
}
|
|
3954
3961
|
/**
|
|
3955
3962
|
* Submit the result of a ways-of-working evaluation.
|
|
3956
|
-
*
|
|
3963
|
+
* Dual output: globalWoW (applies everywhere) and initiative (applies to the task's initiative).
|
|
3957
3964
|
* Clears evaluationPending and isWorking on the task.
|
|
3958
3965
|
*/
|
|
3959
3966
|
async submitEvaluation(input) {
|
|
@@ -7755,19 +7762,9 @@ var Type = type_exports2;
|
|
|
7755
7762
|
var ORCHESTRATOR_TOOLS = {
|
|
7756
7763
|
STATE: {
|
|
7757
7764
|
name: "deskfree_state",
|
|
7758
|
-
description: "Get full workspace state \u2014 all tasks, recently done tasks. Use to assess what needs attention.",
|
|
7765
|
+
description: "Get full workspace state \u2014 all tasks, recently done tasks, active initiatives. Use to assess what needs attention.",
|
|
7759
7766
|
parameters: Type.Object({})
|
|
7760
7767
|
},
|
|
7761
|
-
CREATE_TASK: {
|
|
7762
|
-
name: "deskfree_create_task",
|
|
7763
|
-
description: "Create a new task (starts as bot).",
|
|
7764
|
-
parameters: Type.Object({
|
|
7765
|
-
title: Type.String({ description: "Task title (max 200 chars)" }),
|
|
7766
|
-
instructions: Type.Optional(
|
|
7767
|
-
Type.String({ description: "Detailed instructions for the task" })
|
|
7768
|
-
)
|
|
7769
|
-
})
|
|
7770
|
-
},
|
|
7771
7768
|
START_TASK: {
|
|
7772
7769
|
name: "deskfree_start_task",
|
|
7773
7770
|
description: "Claim a bot task (isWorking=false) and start working. Returns full context (instructions, deliverable, message history).",
|
|
@@ -7833,28 +7830,115 @@ var ORCHESTRATOR_TOOLS = {
|
|
|
7833
7830
|
)
|
|
7834
7831
|
})
|
|
7835
7832
|
},
|
|
7833
|
+
SUGGEST_TASKS: {
|
|
7834
|
+
name: "deskfree_suggest_tasks",
|
|
7835
|
+
description: 'Suggest tasks for human approval. Tasks are created with "suggested" status \u2014 the human approves or rejects each one. Use this to propose work before starting. Include detailed instructions as if briefing a contractor.',
|
|
7836
|
+
parameters: Type.Object({
|
|
7837
|
+
suggestions: Type.Array(
|
|
7838
|
+
Type.Object({
|
|
7839
|
+
title: Type.String({
|
|
7840
|
+
description: "Task title \u2014 short, action-oriented (max 200 chars)"
|
|
7841
|
+
}),
|
|
7842
|
+
instructions: Type.Optional(
|
|
7843
|
+
Type.String({
|
|
7844
|
+
description: "Detailed instructions: what to do, why, what done looks like, known constraints"
|
|
7845
|
+
})
|
|
7846
|
+
),
|
|
7847
|
+
estimatedTokens: Type.Optional(
|
|
7848
|
+
Type.Number({
|
|
7849
|
+
description: "Estimated token cost \u2014 consider files to read, reasoning, output"
|
|
7850
|
+
})
|
|
7851
|
+
),
|
|
7852
|
+
dependsOn: Type.Optional(
|
|
7853
|
+
Type.Array(Type.String(), {
|
|
7854
|
+
description: "Task IDs this suggestion depends on (blocks claiming until those are done)"
|
|
7855
|
+
})
|
|
7856
|
+
),
|
|
7857
|
+
initiativeId: Type.Optional(
|
|
7858
|
+
Type.String({
|
|
7859
|
+
description: "Link to existing initiative ID \u2014 set when this task belongs to an active initiative"
|
|
7860
|
+
})
|
|
7861
|
+
)
|
|
7862
|
+
}),
|
|
7863
|
+
{
|
|
7864
|
+
description: "Array of task suggestions (1-20)",
|
|
7865
|
+
minItems: 1,
|
|
7866
|
+
maxItems: 20
|
|
7867
|
+
}
|
|
7868
|
+
),
|
|
7869
|
+
parentTaskId: Type.Optional(
|
|
7870
|
+
Type.String({
|
|
7871
|
+
description: "Parent task ID \u2014 set when suggesting follow-ups from within a task"
|
|
7872
|
+
})
|
|
7873
|
+
),
|
|
7874
|
+
initiativeSuggestions: Type.Optional(
|
|
7875
|
+
Type.Array(
|
|
7876
|
+
Type.Object({
|
|
7877
|
+
title: Type.String({
|
|
7878
|
+
description: "Initiative title (max 200 chars)"
|
|
7879
|
+
}),
|
|
7880
|
+
content: Type.String({
|
|
7881
|
+
description: "Initiative content markdown \u2014 current state, approach, and next priorities"
|
|
7882
|
+
}),
|
|
7883
|
+
taskRefs: Type.Optional(
|
|
7884
|
+
Type.Array(Type.Number(), {
|
|
7885
|
+
description: "Indexes into suggestions[] to auto-link when this initiative is approved"
|
|
7886
|
+
})
|
|
7887
|
+
)
|
|
7888
|
+
}),
|
|
7889
|
+
{
|
|
7890
|
+
description: 'Propose new initiatives (optional). Created with "suggested" status \u2014 human approves or rejects independently.',
|
|
7891
|
+
minItems: 1,
|
|
7892
|
+
maxItems: 10
|
|
7893
|
+
}
|
|
7894
|
+
)
|
|
7895
|
+
)
|
|
7896
|
+
})
|
|
7897
|
+
},
|
|
7836
7898
|
CLAIM_EVALUATION: {
|
|
7837
7899
|
name: "deskfree_claim_evaluation",
|
|
7838
|
-
description: "Claim a pending ways-of-working evaluation for a task. Returns the task, its message history,
|
|
7900
|
+
description: "Claim a pending ways-of-working evaluation for a task. Returns the task, its message history, current global ways_of_working, and initiative data (if the task belongs to an initiative). Returns null if already claimed by another process.",
|
|
7839
7901
|
parameters: Type.Object({
|
|
7840
7902
|
taskId: Type.String({ description: "Task UUID to claim evaluation for" })
|
|
7841
7903
|
})
|
|
7842
7904
|
},
|
|
7843
7905
|
SUBMIT_EVALUATION: {
|
|
7844
7906
|
name: "deskfree_submit_evaluation",
|
|
7845
|
-
description: "Submit the result of a ways-of-working evaluation. Provide reasoning explaining your analysis.
|
|
7907
|
+
description: "Submit the result of a ways-of-working evaluation. Provide reasoning explaining your analysis. Evaluation has two independent outputs: globalWoW (applies everywhere) and initiative (applies to the specific initiative this task belongs to). Set hasChanges=true and provide updatedContent for each output you want to update.",
|
|
7846
7908
|
parameters: Type.Object({
|
|
7847
7909
|
taskId: Type.String({ description: "Task UUID being evaluated" }),
|
|
7848
7910
|
reasoning: Type.String({
|
|
7849
|
-
description: "Explanation of your evaluation \u2014 what you analyzed and why you did or did not update the ways of working"
|
|
7850
|
-
}),
|
|
7851
|
-
hasChanges: Type.Boolean({
|
|
7852
|
-
description: "Whether the ways of working should be updated"
|
|
7911
|
+
description: "Explanation of your evaluation \u2014 what you analyzed and why you did or did not update the ways of working and/or initiative content"
|
|
7853
7912
|
}),
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7913
|
+
globalWoW: Type.Object(
|
|
7914
|
+
{
|
|
7915
|
+
hasChanges: Type.Boolean({
|
|
7916
|
+
description: "Whether the global ways of working should be updated"
|
|
7917
|
+
}),
|
|
7918
|
+
updatedContent: Type.Optional(
|
|
7919
|
+
Type.String({
|
|
7920
|
+
description: "Full updated global ways-of-working markdown (required if hasChanges=true)"
|
|
7921
|
+
})
|
|
7922
|
+
)
|
|
7923
|
+
},
|
|
7924
|
+
{
|
|
7925
|
+
description: "Global ways-of-working update \u2014 patterns that apply across all work"
|
|
7926
|
+
}
|
|
7927
|
+
),
|
|
7928
|
+
initiative: Type.Object(
|
|
7929
|
+
{
|
|
7930
|
+
hasChanges: Type.Boolean({
|
|
7931
|
+
description: "Whether the initiative content should be updated (ignored if task has no initiative)"
|
|
7932
|
+
}),
|
|
7933
|
+
updatedContent: Type.Optional(
|
|
7934
|
+
Type.String({
|
|
7935
|
+
description: "Full updated initiative content markdown (required if hasChanges=true)"
|
|
7936
|
+
})
|
|
7937
|
+
)
|
|
7938
|
+
},
|
|
7939
|
+
{
|
|
7940
|
+
description: "Initiative content update \u2014 what was learned about this specific area of focus. Ignored if the task has no initiative_id."
|
|
7941
|
+
}
|
|
7858
7942
|
)
|
|
7859
7943
|
})
|
|
7860
7944
|
}
|
|
@@ -8420,14 +8504,22 @@ var deskFreePlugin = {
|
|
|
8420
8504
|
};
|
|
8421
8505
|
|
|
8422
8506
|
// src/context.ts
|
|
8423
|
-
var DESKFREE_AGENT_DIRECTIVE = `## DeskFree
|
|
8424
|
-
Always read the deskfree skill (SKILL.md) at startup. Follow
|
|
8425
|
-
1.
|
|
8426
|
-
2.
|
|
8427
|
-
3.
|
|
8428
|
-
4.
|
|
8429
|
-
5.
|
|
8430
|
-
6.
|
|
8507
|
+
var DESKFREE_AGENT_DIRECTIVE = `## DeskFree \u2014 The Work Loop
|
|
8508
|
+
Always read the deskfree skill (SKILL.md) at startup. Follow the suggest-first work loop:
|
|
8509
|
+
1. **Check state** \u2192 \`deskfree_state\` \u2014 see what needs attention, read ways of working.
|
|
8510
|
+
2. **Suggest tasks** \u2192 \`deskfree_suggest_tasks\` \u2014 ALL work requires human-approved tasks first.
|
|
8511
|
+
3. **Claim a task** \u2192 \`deskfree_start_task\` \u2014 read instructions + parent context carefully.
|
|
8512
|
+
4. **Do the work** \u2192 \`deskfree_update_deliverable\` incrementally from the start.
|
|
8513
|
+
5. **Suggest follow-ups** \u2192 if work reveals more to do, suggest them (strongest when you have full context).
|
|
8514
|
+
6. **Complete** \u2192 \`deskfree_complete_task\` \u2014 deliverable required for "done".
|
|
8515
|
+
7. **Evaluate** \u2192 check \`pendingEvaluations\` and update ways of working.
|
|
8516
|
+
|
|
8517
|
+
Key principles:
|
|
8518
|
+
- You're building a chain. Your instructions become someone else's brief. Your deliverable becomes someone else's context.
|
|
8519
|
+
- Write instructions as if briefing a contractor who has never seen the codebase.
|
|
8520
|
+
- MUST update deliverable before completing with outcome "done".
|
|
8521
|
+
- Estimate token cost per suggestion \u2014 consider files to read, reasoning, output.
|
|
8522
|
+
- Sub-agents get 4 tools: update_deliverable, complete_task, send_message, submit_evaluation.`;
|
|
8431
8523
|
function getDeskFreeContext() {
|
|
8432
8524
|
return `${DESKFREE_AGENT_DIRECTIVE}
|
|
8433
8525
|
|
|
@@ -8634,37 +8726,6 @@ function createOrchestratorTools(api) {
|
|
|
8634
8726
|
}
|
|
8635
8727
|
}
|
|
8636
8728
|
},
|
|
8637
|
-
{
|
|
8638
|
-
...ORCHESTRATOR_TOOLS.CREATE_TASK,
|
|
8639
|
-
async execute(_id, params) {
|
|
8640
|
-
try {
|
|
8641
|
-
const title = validateStringParam(params, "title", true);
|
|
8642
|
-
const instructions = validateStringParam(
|
|
8643
|
-
params,
|
|
8644
|
-
"instructions",
|
|
8645
|
-
false
|
|
8646
|
-
);
|
|
8647
|
-
const task = await client.createTask({
|
|
8648
|
-
title,
|
|
8649
|
-
instructions
|
|
8650
|
-
});
|
|
8651
|
-
await client.sendMessage({
|
|
8652
|
-
content: `\u{1F4CB} Created task: "${task.title}"`
|
|
8653
|
-
}).catch(() => {
|
|
8654
|
-
});
|
|
8655
|
-
return formatTaskResponse(
|
|
8656
|
-
task,
|
|
8657
|
-
`Created task "${task.title}" with ID ${task.taskId}`,
|
|
8658
|
-
[
|
|
8659
|
-
"Claim and start this task with deskfree_start_task",
|
|
8660
|
-
"Or check workspace state with deskfree_state"
|
|
8661
|
-
]
|
|
8662
|
-
);
|
|
8663
|
-
} catch (err) {
|
|
8664
|
-
return errorResult(err);
|
|
8665
|
-
}
|
|
8666
|
-
}
|
|
8667
|
-
},
|
|
8668
8729
|
{
|
|
8669
8730
|
...ORCHESTRATOR_TOOLS.START_TASK,
|
|
8670
8731
|
async execute(_id, params) {
|
|
@@ -8806,6 +8867,95 @@ function createOrchestratorTools(api) {
|
|
|
8806
8867
|
}
|
|
8807
8868
|
}
|
|
8808
8869
|
},
|
|
8870
|
+
{
|
|
8871
|
+
...ORCHESTRATOR_TOOLS.SUGGEST_TASKS,
|
|
8872
|
+
async execute(_id, params) {
|
|
8873
|
+
try {
|
|
8874
|
+
const rawSuggestions = params?.suggestions;
|
|
8875
|
+
if (!Array.isArray(rawSuggestions) || rawSuggestions.length === 0) {
|
|
8876
|
+
throw new Error(
|
|
8877
|
+
'Parameter "suggestions" must be a non-empty array'
|
|
8878
|
+
);
|
|
8879
|
+
}
|
|
8880
|
+
const suggestions = rawSuggestions.map((s, i) => {
|
|
8881
|
+
if (typeof s !== "object" || s === null) {
|
|
8882
|
+
throw new Error(`suggestions[${i}] must be an object`);
|
|
8883
|
+
}
|
|
8884
|
+
const item = s;
|
|
8885
|
+
const title = item["title"];
|
|
8886
|
+
if (typeof title !== "string" || title.trim() === "") {
|
|
8887
|
+
throw new Error(
|
|
8888
|
+
`suggestions[${i}].title must be a non-empty string`
|
|
8889
|
+
);
|
|
8890
|
+
}
|
|
8891
|
+
return {
|
|
8892
|
+
title: title.trim(),
|
|
8893
|
+
instructions: typeof item["instructions"] === "string" ? item["instructions"] : void 0,
|
|
8894
|
+
estimatedTokens: typeof item["estimatedTokens"] === "number" ? item["estimatedTokens"] : void 0,
|
|
8895
|
+
dependsOn: Array.isArray(item["dependsOn"]) ? item["dependsOn"] : void 0,
|
|
8896
|
+
initiativeId: typeof item["initiativeId"] === "string" ? item["initiativeId"] : void 0
|
|
8897
|
+
};
|
|
8898
|
+
});
|
|
8899
|
+
const parentTaskId = validateStringParam(
|
|
8900
|
+
params,
|
|
8901
|
+
"parentTaskId",
|
|
8902
|
+
false
|
|
8903
|
+
);
|
|
8904
|
+
const rawInitiativeSuggestions = params?.initiativeSuggestions;
|
|
8905
|
+
let initiativeSuggestions;
|
|
8906
|
+
if (Array.isArray(rawInitiativeSuggestions) && rawInitiativeSuggestions.length > 0) {
|
|
8907
|
+
initiativeSuggestions = rawInitiativeSuggestions.map(
|
|
8908
|
+
(s, i) => {
|
|
8909
|
+
if (typeof s !== "object" || s === null) {
|
|
8910
|
+
throw new Error(`initiativeSuggestions[${i}] must be an object`);
|
|
8911
|
+
}
|
|
8912
|
+
const item = s;
|
|
8913
|
+
const title = item["title"];
|
|
8914
|
+
if (typeof title !== "string" || title.trim() === "") {
|
|
8915
|
+
throw new Error(
|
|
8916
|
+
`initiativeSuggestions[${i}].title must be a non-empty string`
|
|
8917
|
+
);
|
|
8918
|
+
}
|
|
8919
|
+
const content = item["content"];
|
|
8920
|
+
if (typeof content !== "string") {
|
|
8921
|
+
throw new Error(
|
|
8922
|
+
`initiativeSuggestions[${i}].content must be a string`
|
|
8923
|
+
);
|
|
8924
|
+
}
|
|
8925
|
+
return {
|
|
8926
|
+
title: title.trim(),
|
|
8927
|
+
content,
|
|
8928
|
+
taskRefs: Array.isArray(item["taskRefs"]) ? item["taskRefs"] : void 0
|
|
8929
|
+
};
|
|
8930
|
+
}
|
|
8931
|
+
);
|
|
8932
|
+
}
|
|
8933
|
+
const result = await client.suggestTasksDedicated({
|
|
8934
|
+
suggestions,
|
|
8935
|
+
parentTaskId,
|
|
8936
|
+
initiativeSuggestions
|
|
8937
|
+
});
|
|
8938
|
+
const initiativeCount = initiativeSuggestions?.length ?? 0;
|
|
8939
|
+
const summaryParts = [
|
|
8940
|
+
`Suggested ${suggestions.length} task${suggestions.length === 1 ? "" : "s"} for human approval`,
|
|
8941
|
+
...initiativeCount > 0 ? [
|
|
8942
|
+
`and ${initiativeCount} initiative${initiativeCount === 1 ? "" : "s"}`
|
|
8943
|
+
] : []
|
|
8944
|
+
];
|
|
8945
|
+
return formatConfirmation(
|
|
8946
|
+
summaryParts.join(" "),
|
|
8947
|
+
[
|
|
8948
|
+
'Tasks created with "suggested" status \u2014 human will approve or reject each',
|
|
8949
|
+
...initiativeCount > 0 ? ["Initiative suggestions created \u2014 human will approve or reject independently"] : [],
|
|
8950
|
+
"Use deskfree_state to check for approved tasks"
|
|
8951
|
+
],
|
|
8952
|
+
result
|
|
8953
|
+
);
|
|
8954
|
+
} catch (err) {
|
|
8955
|
+
return errorResult(err);
|
|
8956
|
+
}
|
|
8957
|
+
}
|
|
8958
|
+
},
|
|
8809
8959
|
{
|
|
8810
8960
|
...ORCHESTRATOR_TOOLS.CLAIM_EVALUATION,
|
|
8811
8961
|
async execute(_id, params) {
|
|
@@ -8826,14 +8976,15 @@ function createOrchestratorTools(api) {
|
|
|
8826
8976
|
{
|
|
8827
8977
|
summary: `Claimed evaluation for task "${result.task.title}"`,
|
|
8828
8978
|
nextActions: [
|
|
8829
|
-
"Review the task messages
|
|
8830
|
-
"Decide
|
|
8979
|
+
"Review the task messages, current global ways of working, and initiative content (if present)",
|
|
8980
|
+
"Decide what to update: globalWoW (universal patterns), initiative (area-specific learnings), both, or neither",
|
|
8831
8981
|
"Call deskfree_submit_evaluation with your analysis"
|
|
8832
8982
|
],
|
|
8833
8983
|
task: result.task,
|
|
8834
8984
|
waysOfWorking: result.waysOfWorking,
|
|
8835
8985
|
currentVersion: result.currentVersion,
|
|
8836
|
-
messages: result.messages
|
|
8986
|
+
messages: result.messages,
|
|
8987
|
+
...result.initiative ? { initiative: result.initiative } : {}
|
|
8837
8988
|
},
|
|
8838
8989
|
null,
|
|
8839
8990
|
2
|
|
@@ -8852,26 +9003,53 @@ function createOrchestratorTools(api) {
|
|
|
8852
9003
|
try {
|
|
8853
9004
|
const taskId = validateStringParam(params, "taskId", true);
|
|
8854
9005
|
const reasoning = validateStringParam(params, "reasoning", true);
|
|
8855
|
-
const
|
|
8856
|
-
if (typeof
|
|
8857
|
-
throw new Error('Parameter "
|
|
9006
|
+
const rawGlobalWoW = params?.globalWoW;
|
|
9007
|
+
if (typeof rawGlobalWoW !== "object" || rawGlobalWoW === null) {
|
|
9008
|
+
throw new Error('Parameter "globalWoW" must be an object');
|
|
8858
9009
|
}
|
|
8859
|
-
const
|
|
8860
|
-
|
|
8861
|
-
"
|
|
8862
|
-
|
|
8863
|
-
|
|
9010
|
+
const globalWoWObj = rawGlobalWoW;
|
|
9011
|
+
if (typeof globalWoWObj["hasChanges"] !== "boolean") {
|
|
9012
|
+
throw new Error('Parameter "globalWoW.hasChanges" must be a boolean');
|
|
9013
|
+
}
|
|
9014
|
+
const globalWoW = {
|
|
9015
|
+
hasChanges: globalWoWObj["hasChanges"],
|
|
9016
|
+
updatedContent: typeof globalWoWObj["updatedContent"] === "string" ? globalWoWObj["updatedContent"] : void 0
|
|
9017
|
+
};
|
|
9018
|
+
const rawInitiative = params?.initiative;
|
|
9019
|
+
if (typeof rawInitiative !== "object" || rawInitiative === null) {
|
|
9020
|
+
throw new Error('Parameter "initiative" must be an object');
|
|
9021
|
+
}
|
|
9022
|
+
const initiativeObj = rawInitiative;
|
|
9023
|
+
if (typeof initiativeObj["hasChanges"] !== "boolean") {
|
|
9024
|
+
throw new Error('Parameter "initiative.hasChanges" must be a boolean');
|
|
9025
|
+
}
|
|
9026
|
+
const initiative = {
|
|
9027
|
+
hasChanges: initiativeObj["hasChanges"],
|
|
9028
|
+
updatedContent: typeof initiativeObj["updatedContent"] === "string" ? initiativeObj["updatedContent"] : void 0
|
|
9029
|
+
};
|
|
8864
9030
|
const result = await client.submitEvaluation({
|
|
8865
9031
|
taskId,
|
|
8866
9032
|
reasoning,
|
|
8867
|
-
|
|
8868
|
-
|
|
9033
|
+
globalWoW,
|
|
9034
|
+
initiative
|
|
8869
9035
|
});
|
|
8870
|
-
const
|
|
9036
|
+
const parts = [];
|
|
9037
|
+
if (globalWoW.hasChanges) {
|
|
9038
|
+
parts.push(`global WoW \u2192 v${result.globalVersion}`);
|
|
9039
|
+
}
|
|
9040
|
+
if (initiative.hasChanges && result.initiativeVersion !== void 0) {
|
|
9041
|
+
parts.push(`initiative \u2192 v${result.initiativeVersion}`);
|
|
9042
|
+
}
|
|
9043
|
+
const messageContent = parts.length > 0 ? `\u{1F4DD} Updated ${parts.join(", ")}: ${reasoning}` : `\u{1F4DD} No updates to ways of working: ${reasoning}`;
|
|
8871
9044
|
await client.sendMessage({ content: messageContent, taskId }).catch(() => {
|
|
8872
9045
|
});
|
|
9046
|
+
const summaryParts = [];
|
|
9047
|
+
if (globalWoW.hasChanges) summaryParts.push(`global WoW v${result.globalVersion}`);
|
|
9048
|
+
if (initiative.hasChanges && result.initiativeVersion !== void 0) {
|
|
9049
|
+
summaryParts.push(`initiative v${result.initiativeVersion}`);
|
|
9050
|
+
}
|
|
8873
9051
|
return formatConfirmation(
|
|
8874
|
-
|
|
9052
|
+
summaryParts.length > 0 ? `Evaluation complete \u2014 updated ${summaryParts.join(", ")}` : "Evaluation complete \u2014 no changes needed",
|
|
8875
9053
|
["Use deskfree_state to check for other pending evaluations"],
|
|
8876
9054
|
result
|
|
8877
9055
|
);
|