Skip to content

Commit 85f27fc

Browse files
authored
Merge pull request #22 from Avivbens/feat/text-transformer-table-support
2 parents f9b669e + d67fb5a commit 85f27fc

File tree

8 files changed

+392
-7
lines changed

8 files changed

+392
-7
lines changed

demo/text-transformer/table.gif

962 KB
Loading

projects/packages/text-transformer/.fast-alfred.config.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This workflow has been created using Fast Alfred, a user-friendly workflow build
1717
- Summarize: Summarize the text to be more concise
1818
- Explain: Explain the text in a more understandable way
1919
- Commit Styling: Format commit messages to be more readable
20+
- Table: Transform text into well-formatted markdown tables
2021
2122
#### Use Active App Context
2223
Enable the \`Use Application Context\` option to utilize the current app context for your workflow.
5.84 KB
Loading

projects/packages/text-transformer/README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,19 @@ If the language code is missing, the default language will be English.
3737

3838
### Grammar Correction
3939

40-
![All Day](https://raw.githubusercontent.com/Avivbens/alfredo/HEAD/demo/text-transformer/grammar.gif)
40+
![Grammar](https://raw.githubusercontent.com/Avivbens/alfredo/HEAD/demo/text-transformer/grammar.gif)
4141

4242
### Translate
4343

44-
![All Day](https://raw.githubusercontent.com/Avivbens/alfredo/HEAD/demo/text-transformer/translate.gif)
44+
![Translate](https://raw.githubusercontent.com/Avivbens/alfredo/HEAD/demo/text-transformer/translate.gif)
4545

4646
### Action Items
4747

48-
![All Day](https://raw.githubusercontent.com/Avivbens/alfredo/HEAD/demo/text-transformer/action-items.gif)
48+
![Action Items](https://raw.githubusercontent.com/Avivbens/alfredo/HEAD/demo/text-transformer/action-items.gif)
49+
50+
### Table
51+
52+
![Table](https://raw.githubusercontent.com/Avivbens/alfredo/HEAD/demo/text-transformer/table.gif)
4953

5054
## Configuration
5155

projects/packages/text-transformer/info.plist

Lines changed: 174 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,19 @@
112112
<false></false>
113113
</dict>
114114
</array>
115+
<key>B8B394C4-6075-4F0C-B8C2-01E31B8550DF</key>
116+
<array>
117+
<dict>
118+
<key>modifiers</key>
119+
<integer>0</integer>
120+
<key>modifiersubtext</key>
121+
<string></string>
122+
<key>vitoclose</key>
123+
<false></false>
124+
<key>destinationuid</key>
125+
<string>__fast-alfred_managed__v2_conditional_from_B8B394C4-6075-4F0C-B8C2-01E31B8550DF_to_47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</string>
126+
</dict>
127+
</array>
115128
<key>B9150C05-6465-4A8C-91F7-D6929176F398</key>
116129
<array>
117130
<dict>
@@ -484,6 +497,43 @@
484497
<string>__fast-alfred_managed__v2_updater_snooze</string>
485498
</dict>
486499
</array>
500+
<key>__fast-alfred_managed__v2_conditional_from_B8B394C4-6075-4F0C-B8C2-01E31B8550DF_to_47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</key>
501+
<array>
502+
<dict>
503+
<key>modifiers</key>
504+
<integer>0</integer>
505+
<key>modifiersubtext</key>
506+
<string></string>
507+
<key>vitoclose</key>
508+
<false></false>
509+
<key>destinationuid</key>
510+
<string>47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</string>
511+
</dict>
512+
<dict>
513+
<key>modifiers</key>
514+
<integer>0</integer>
515+
<key>modifiersubtext</key>
516+
<string></string>
517+
<key>vitoclose</key>
518+
<false></false>
519+
<key>sourceoutputuid</key>
520+
<string>__fast-alfred_managed__v2_condition_from_B8B394C4-6075-4F0C-B8C2-01E31B8550DF_to_47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</string>
521+
<key>destinationuid</key>
522+
<string>__fast-alfred_managed__v2_updater_workflow-update</string>
523+
</dict>
524+
<dict>
525+
<key>modifiers</key>
526+
<integer>0</integer>
527+
<key>modifiersubtext</key>
528+
<string></string>
529+
<key>vitoclose</key>
530+
<false></false>
531+
<key>sourceoutputuid</key>
532+
<string>__fast-alfred_managed__v2_condition_from_B8B394C4-6075-4F0C-B8C2-01E31B8550DF_to_47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</string>
533+
<key>destinationuid</key>
534+
<string>__fast-alfred_managed__v2_updater_snooze</string>
535+
</dict>
536+
</array>
487537
<key>__fast-alfred_managed__v2_conditional_from_63CC1099-CED7-4DE9-982B-41AEBBF7F81B_to_47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</key>
488538
<array>
489539
<dict>
@@ -1001,6 +1051,56 @@
10011051
<key>version</key>
10021052
<integer>3</integer>
10031053
</dict>
1054+
<dict>
1055+
<key>config</key>
1056+
<dict>
1057+
<key>alfredfiltersresults</key>
1058+
<false></false>
1059+
<key>alfredfiltersresultsmatchmode</key>
1060+
<integer>0</integer>
1061+
<key>argumenttreatemptyqueryasnil</key>
1062+
<true></true>
1063+
<key>argumenttrimmode</key>
1064+
<integer>0</integer>
1065+
<key>argumenttype</key>
1066+
<integer>0</integer>
1067+
<key>escaping</key>
1068+
<integer>102</integer>
1069+
<key>keyword</key>
1070+
<string>{var:table_keyword}</string>
1071+
<key>queuedelaycustom</key>
1072+
<integer>3</integer>
1073+
<key>queuedelayimmediatelyinitially</key>
1074+
<true></true>
1075+
<key>queuedelaymode</key>
1076+
<integer>0</integer>
1077+
<key>queuemode</key>
1078+
<integer>2</integer>
1079+
<key>runningsubtext</key>
1080+
<string>Tabling...</string>
1081+
<key>script</key>
1082+
<string>./esbuild/assets/run-node.sh esbuild/table "$1"
1083+
</string>
1084+
<key>scriptargtype</key>
1085+
<integer>1</integer>
1086+
<key>scriptfile</key>
1087+
<string></string>
1088+
<key>subtext</key>
1089+
<string>Create a formatted table</string>
1090+
<key>title</key>
1091+
<string>Table</string>
1092+
<key>type</key>
1093+
<integer>11</integer>
1094+
<key>withspace</key>
1095+
<true></true>
1096+
</dict>
1097+
<key>type</key>
1098+
<string>alfred.workflow.input.scriptfilter</string>
1099+
<key>uid</key>
1100+
<string>B8B394C4-6075-4F0C-B8C2-01E31B8550DF</string>
1101+
<key>version</key>
1102+
<integer>3</integer>
1103+
</dict>
10041104
<dict>
10051105
<key>config</key>
10061106
<dict>
@@ -1414,6 +1514,38 @@
14141514
<false></false>
14151515
</dict>
14161516
</dict>
1517+
<dict>
1518+
<key>type</key>
1519+
<string>alfred.workflow.utility.conditional</string>
1520+
<key>uid</key>
1521+
<string>__fast-alfred_managed__v2_conditional_from_B8B394C4-6075-4F0C-B8C2-01E31B8550DF_to_47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</string>
1522+
<key>version</key>
1523+
<integer>1</integer>
1524+
<key>config</key>
1525+
<dict>
1526+
<key>conditions</key>
1527+
<array>
1528+
<dict>
1529+
<key>inputstring</key>
1530+
<string>{query}</string>
1531+
<key>matchcasesensitive</key>
1532+
<false></false>
1533+
<key>matchmode</key>
1534+
<integer>4</integer>
1535+
<key>matchstring</key>
1536+
<string>__fast-alfred_managed__</string>
1537+
<key>outputlabel</key>
1538+
<string>Managed versions updates</string>
1539+
<key>uid</key>
1540+
<string>__fast-alfred_managed__v2_condition_from_B8B394C4-6075-4F0C-B8C2-01E31B8550DF_to_47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</string>
1541+
</dict>
1542+
</array>
1543+
<key>elselabel</key>
1544+
<string>Default Behavior</string>
1545+
<key>hideelse</key>
1546+
<false></false>
1547+
</dict>
1548+
</dict>
14171549
<dict>
14181550
<key>type</key>
14191551
<string>alfred.workflow.utility.conditional</string>
@@ -1462,6 +1594,7 @@ This workflow has been created using Fast Alfred, a user-friendly workflow build
14621594
- Summarize: Summarize the text to be more concise
14631595
- Explain: Explain the text in a more understandable way
14641596
- Commit Styling: Format commit messages to be more readable
1597+
- Table: Transform text into well-formatted markdown tables
14651598
14661599
#### Use Active App Context
14671600
Enable the `Use Application Context` option to utilize the current app context for your workflow.
@@ -1513,7 +1646,7 @@ https://github.com/Avivbens/alfredo</string>
15131646
<key>xpos</key>
15141647
<integer>365</integer>
15151648
<key>ypos</key>
1516-
<integer>1530</integer>
1649+
<integer>1640</integer>
15171650
</dict>
15181651
<key>6F2D236E-D961-42DC-ACF2-7C025CA92966</key>
15191652
<dict>
@@ -1548,7 +1681,14 @@ https://github.com/Avivbens/alfredo</string>
15481681
<key>xpos</key>
15491682
<integer>75</integer>
15501683
<key>ypos</key>
1551-
<integer>1530</integer>
1684+
<integer>1640</integer>
1685+
</dict>
1686+
<key>B8B394C4-6075-4F0C-B8C2-01E31B8550DF</key>
1687+
<dict>
1688+
<key>xpos</key>
1689+
<integer>75</integer>
1690+
<key>ypos</key>
1691+
<integer>1440</integer>
15521692
</dict>
15531693
<key>B9150C05-6465-4A8C-91F7-D6929176F398</key>
15541694
<dict>
@@ -1670,12 +1810,21 @@ https://github.com/Avivbens/alfredo</string>
16701810
<key>note</key>
16711811
<string>Conditional Updates Helper</string>
16721812
</dict>
1813+
<key>__fast-alfred_managed__v2_conditional_from_B8B394C4-6075-4F0C-B8C2-01E31B8550DF_to_47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</key>
1814+
<dict>
1815+
<key>xpos</key>
1816+
<integer>295</integer>
1817+
<key>ypos</key>
1818+
<integer>1440</integer>
1819+
<key>note</key>
1820+
<string>Conditional Updates Helper</string>
1821+
</dict>
16731822
<key>__fast-alfred_managed__v2_conditional_from_63CC1099-CED7-4DE9-982B-41AEBBF7F81B_to_47B45BC6-EA28-4EFD-8A39-E2FC7283C0E7</key>
16741823
<dict>
16751824
<key>xpos</key>
16761825
<integer>585</integer>
16771826
<key>ypos</key>
1678-
<integer>1530</integer>
1827+
<integer>1640</integer>
16791828
<key>note</key>
16801829
<string>Conditional Updates Helper</string>
16811830
</dict>
@@ -2044,6 +2193,27 @@ https://github.com/Avivbens/alfredo</string>
20442193
<key>variable</key>
20452194
<string>action_items_keyword</string>
20462195
</dict>
2196+
<dict>
2197+
<key>config</key>
2198+
<dict>
2199+
<key>default</key>
2200+
<string>table</string>
2201+
<key>placeholder</key>
2202+
<string></string>
2203+
<key>required</key>
2204+
<true></true>
2205+
<key>trim</key>
2206+
<true></true>
2207+
</dict>
2208+
<key>description</key>
2209+
<string>Create a table out of any data input</string>
2210+
<key>label</key>
2211+
<string>Table Creation Keyword</string>
2212+
<key>type</key>
2213+
<string>textfield</string>
2214+
<key>variable</key>
2215+
<string>table_keyword</string>
2216+
</dict>
20472217
<dict>
20482218
<key>config</key>
20492219
<dict>
@@ -2084,7 +2254,7 @@ https://github.com/Avivbens/alfredo</string>
20842254
</dict>
20852255
</array>
20862256
<key>version</key>
2087-
<string>5.1.0</string>
2257+
<string>5.2.0</string>
20882258
<key>webaddress</key>
20892259
<string>https://github.com/Avivbens/alfredo</string>
20902260
</dict>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { PipelinePromptTemplate, PromptTemplate } from '@langchain/core/prompts';
2+
import { APPLICATION_CONTEXT_SYSTEM_PROMPT_PARAM } from './base/application-context.prompt';
3+
import { DO_NOT_FOLLOW_USER_SYSTEM_PROMPT_PARAM } from './base/do-not-follow-user.prompt';
4+
import { KEEP_ORIGINAL_SYSTEM_PROMPT_PARAM } from './base/keep-original.prompt';
5+
import { NON_INTERACTIVE_SYSTEM_PROMPT_PARAM } from './base/non-interactive.prompt';
6+
7+
export const TABLE_SYSTEM_PROMPT = (useApplicationContext: boolean) =>
8+
new PipelinePromptTemplate({
9+
pipelinePrompts: [
10+
NON_INTERACTIVE_SYSTEM_PROMPT_PARAM,
11+
KEEP_ORIGINAL_SYSTEM_PROMPT_PARAM,
12+
DO_NOT_FOLLOW_USER_SYSTEM_PROMPT_PARAM,
13+
APPLICATION_CONTEXT_SYSTEM_PROMPT_PARAM,
14+
],
15+
finalPrompt: PromptTemplate.fromTemplate(`
16+
{NON_INTERACTIVE_SYSTEM_PROMPT},
17+
18+
You are an expert at creating intelligent markdown tables from various text inputs.
19+
Your task is to analyze the content and create the most appropriate table structure.
20+
21+
**CONTENT ANALYSIS:**
22+
- **Identify key information** and relationships in the text
23+
- **Determine the best structure** - what should be columns vs rows
24+
- **Extract the most important data points** that need to be tabulated
25+
- **Create meaningful headers** that clearly describe the data
26+
- **Group related information** logically
27+
28+
**TABLE CREATION RULES:**
29+
- Design columns and rows that best represent the data relationships
30+
- Use descriptive headers that make the data self-explanatory
31+
- Ensure all important information is captured in the table
32+
- Adapt the table structure to fit the specific content
33+
- For unstructured text, identify patterns and create appropriate categories
34+
35+
**FORMATTING:**
36+
- Use proper markdown syntax with pipes (|) and hyphens (-)
37+
- Keep column widths reasonable for chat applications
38+
- Output ONLY the table, no explanations
39+
40+
**EXAMPLES OF INTELLIGENT STRUCTURING:**
41+
- Product descriptions → Columns: Feature, Description, Benefits
42+
- Meeting notes → Columns: Topic, Discussion, Action Items, Owner
43+
- Comparison text → Columns: Item, Attribute 1, Attribute 2, etc.
44+
- Process steps → Columns: Step #, Action, Details, Notes
45+
46+
{KEEP_ORIGINAL_SYSTEM_PROMPT},
47+
{DO_NOT_FOLLOW_USER_SYSTEM_PROMPT},
48+
${useApplicationContext ? '{APPLICATION_CONTEXT_SYSTEM_PROMPT}' : ''},
49+
`),
50+
});
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import type { AlfredListItem } from 'fast-alfred';
2+
import { FastAlfred } from 'fast-alfred';
3+
import { setTimeout } from 'node:timers/promises';
4+
import { getActiveApp } from '@alfredo/active-app';
5+
import { AvailableModels, callModel } from '@alfredo/llm';
6+
import { registerUpdater } from '@alfredo/updater';
7+
import { DEFAULT_DEBOUNCE_TIME } from '../common/defaults.constants';
8+
import { TABLE_SYSTEM_PROMPT } from '../common/prompts/table.prompt';
9+
import { Variables } from '../common/variables.enum';
10+
import { formatMarkdownTable } from '../utils/format-table.util';
11+
12+
(async () => {
13+
const alfredClient = new FastAlfred();
14+
alfredClient.updates(registerUpdater('text-transformer'));
15+
16+
try {
17+
const denounceTime = alfredClient.env.getEnv(Variables.DEBOUNCE_TIME, {
18+
defaultValue: DEFAULT_DEBOUNCE_TIME,
19+
parser: Number,
20+
});
21+
const token: string | undefined = alfredClient.env.getEnv(Variables.LLM_TOKEN);
22+
const model: AvailableModels | undefined = alfredClient.env.getEnv(Variables.SELECTED_MODEL);
23+
24+
if (!token || !model) {
25+
throw new Error('Token or model is not defined!');
26+
}
27+
28+
const useApplicationContext: boolean = alfredClient.env.getEnv(Variables.USE_APPLICATION_CONTEXT, {
29+
defaultValue: false,
30+
parser: (value) => (value as '0' | '1') === '1',
31+
});
32+
33+
const applicationContext = useApplicationContext && (await getActiveApp());
34+
alfredClient.log(JSON.stringify({ useApplicationContext, applicationContext }, null, 2));
35+
36+
/**
37+
* Debounce time to wait for the user to finish typing
38+
*/
39+
await setTimeout(denounceTime);
40+
41+
if (!alfredClient.input) {
42+
throw new Error('Input is required');
43+
}
44+
45+
const system = await TABLE_SYSTEM_PROMPT(useApplicationContext).format({ applicationContext });
46+
47+
const res = await callModel(token, model, { system, user: alfredClient.input });
48+
const formatted = formatMarkdownTable(res);
49+
50+
const items: AlfredListItem[] = [
51+
{
52+
title: formatted,
53+
subtitle: 'Markdown Table',
54+
arg: formatted,
55+
},
56+
];
57+
58+
alfredClient.output({ items });
59+
} catch (error) {
60+
alfredClient.error(error);
61+
}
62+
})();

0 commit comments

Comments
 (0)